refactor: Wait-puljen udskilt i adWaitPool (reservationer, rutetjek, redirect) til deling med udkørsel

This commit is contained in:
2026-09-23 09:47:47 +02:00
parent 68ad63ce1f
commit def054ca43
6 changed files with 233 additions and 78 deletions
+13 -76
View File
@@ -18,8 +18,6 @@ ADUnloadWait.LOG_PREFIX = "ADSmartPickup: "
-- køretøj -> {task, homeDestinationID, waitMarker, fillType, rest}
local waits = setmetatable({}, {__mode = "k"})
-- markør-id -> køretøj der har reserveret Wait-punktet
local claims = setmetatable({}, {__mode = "v"})
local warnedNoWaitPoint = setmetatable({}, {__mode = "k"})
local isInstalled = false
@@ -39,72 +37,23 @@ local function getRestLoad(adEnv, vehicle)
return bestFillType, bestLevel
end
-- poolGroup: run'ets Wait-mappe; tom/nil = alle Wait-mapper.
local function getWaitCandidates(adEnv, poolGroup)
local candidates = {}
for _, marker in pairs(adEnv.ADGraphManager:getMapMarkers()) do
local isInPool = poolGroup == nil or poolGroup == "" or marker.group == poolGroup
if isInPool and ADSupplyPlanner.isWaitMarker(marker) then
local wayPoint = adEnv.ADGraphManager:getWayPointById(marker.id)
if wayPoint ~= nil then
table.insert(candidates, {marker = marker, x = wayPoint.x, z = wayPoint.z})
end
end
end
return candidates
end
local function getWaitPoolGroup(vehicle)
local run = ADRunsController ~= nil and ADRunsController.getRunForVehicle(vehicle) or nil
return run ~= nil and run.waitPoolGroup or nil
end
local function getVehiclePosition(vehicle)
if vehicle.rootNode == nil then
return nil
end
local x, _, z = getWorldTranslation(vehicle.rootNode)
return x, z
end
-- Ender ruten i målet? (AutoDrive returnerer tom/afkortet liste når der ingen vej er.)
local function pathReaches(path, wayPointId)
return path ~= nil and #path > 0 and path[#path].id == wayPointId
end
-- Findes der vejnet fra køretøjet til Wait-punktet OG fra Wait-punktet hjem til målet?
-- Sendes AutoDrive mod et punkt uden rute, viser den "cannot reach" og slukker sig selv.
-- getPathTo/pathFromTo er rene opslag uden bivirkninger.
-- Kun "til punktet": ved aflæsning af (forkert) last i en silo er næste tur AD's egen
-- rute fra siloen, så "fra siloen hjem" er ikke et krav.
-- Rutetjek, reservationer og omdirigering deles med udkørsels-modulet (adWaitPool).
-- Kun "til punktet" ved silo-aflæsning: næste tur er AD's egen rute fra siloen.
local function hasRouteTo(adEnv, vehicle, wayPointId)
local graph = adEnv.ADGraphManager
if graph.getPathTo == nil then
return true
end
return pathReaches(graph:getPathTo(vehicle, wayPointId), wayPointId)
return ADWaitPool.hasRouteTo(adEnv, vehicle, wayPointId)
end
local function hasRouteBothWays(adEnv, vehicle, waitWayPointId, homeWayPointId)
local graph = adEnv.ADGraphManager
if graph.getPathTo == nil or graph.pathFromTo == nil then
return true
end
return pathReaches(graph:getPathTo(vehicle, waitWayPointId), waitWayPointId)
and pathReaches(graph:pathFromTo(waitWayPointId, homeWayPointId), homeWayPointId)
return ADWaitPool.hasRouteBothWays(adEnv, vehicle, waitWayPointId, homeWayPointId)
end
-- Står AD midt i en (blokeret) aflæsning, stoppes den pænt først — ellers kører traktoren
-- væk med tippet vogn.
local function redirect(task, destinationID)
local trailerModule = task.vehicle.ad.trailerModule
if trailerModule ~= nil and trailerModule.isActiveAtTrigger ~= nil and trailerModule:isActiveAtTrigger() then
if trailerModule.stopUnloading ~= nil then trailerModule:stopUnloading() end
if trailerModule.stopLoading ~= nil then trailerModule:stopLoading() end
end
task.destinationID = destinationID
task.state = ADUnloadWait.STATE_DRIVING
task.vehicle.ad.drivePathModule:setPathTo(destinationID)
ADWaitPool.redirect(task, destinationID)
end
-- køretøj -> AD's oprindelige 2. markør (waypoint-id) mens der læsses af i en silo
@@ -137,9 +86,8 @@ local function restoreTarget(vehicle)
end
local function release(vehicle)
local wait = waits[vehicle]
if wait ~= nil and claims[wait.waitMarker.id] == vehicle then
claims[wait.waitMarker.id] = nil
if waits[vehicle] ~= nil then
ADWaitPool.releaseVehicle(vehicle)
end
waits[vehicle] = nil
if ADLoadSwap ~= nil then
@@ -199,12 +147,11 @@ local function startWaiting(adEnv, task)
return
end
local x, z = getVehiclePosition(vehicle)
local isReachable = function(candidate)
return hasRouteBothWays(adEnv, vehicle, candidate.marker.id, task.destinationID)
end
local pool = getWaitPoolGroup(vehicle)
local candidate = x ~= nil and ADSupplyPlanner.pickNearestFreeWaitPoint(getWaitCandidates(adEnv, pool), claims, x, z, vehicle, isReachable) or nil
local candidate = ADWaitPool.pickFree(adEnv, vehicle, pool, isReachable)
if candidate == nil then
if not warnedNoWaitPoint[vehicle] then
warnedNoWaitPoint[vehicle] = true
@@ -214,7 +161,7 @@ local function startWaiting(adEnv, task)
return
end
warnedNoWaitPoint[vehicle] = nil
claims[candidate.marker.id] = vehicle
ADWaitPool.claim(candidate.marker.id, vehicle)
waits[vehicle] = {task = task, homeDestinationID = task.destinationID, waitMarker = candidate.marker, fillType = fillType, rest = rest}
-- AD tipper (og holder vognen stille) så længe den står nær sit EGET mål — også i små
-- portioner, når målet forbruger løbende. Derfor peger AD's mål på Wait-punktet imens.
@@ -366,20 +313,9 @@ function ADUnloadWait.getWaitFor(vehicle)
return {markerName = wait.waitMarker ~= nil and wait.waitMarker.name or nil, fillType = wait.fillType, rest = wait.rest}
end
function ADUnloadWait.getClaims()
local result = {}
for _, wait in pairs(waits) do
if wait.waitMarker ~= nil and claims[wait.waitMarker.id] ~= nil then
table.insert(result, {marker = wait.waitMarker, vehicle = claims[wait.waitMarker.id]})
end
end
table.sort(result, function(a, b)
if a.marker.group ~= b.marker.group then
return tostring(a.marker.group) < tostring(b.marker.group)
end
return a.marker.id < b.marker.id
end)
return result
-- Alle reservationer i puljen (også udkørsels-traktorer der holder).
function ADUnloadWait.getClaims(adEnv)
return ADWaitPool.getClaims(adEnv)
end
function ADUnloadWait.install(adEnv)
@@ -389,6 +325,7 @@ function ADUnloadWait.install(adEnv)
end
isInstalled = true
ADUnloadWait.STATE_DRIVING = task.STATE_DRIVING or 2
ADWaitPool.STATE_DRIVING = ADUnloadWait.STATE_DRIVING
local originalUpdate, originalFinished, originalGetSetting = task.update, task.finished, autoDrive.getSetting