perf+fix: rutetjek gemmes 30 s (hak hvert 5. s); kilde der gav lidt hviler 3 min (æg-vognen til samme hønsehus 3x) (v1.27.3.0)

In-game 26/9: hak ca. hvert 5. s efter 1.27.2 = holdende vognes genplanlægning (ADOutbound/ADLoadSwap hvert
5 s) med AD-stifinding + reserve-BFS gennem 13.550 waypoints pr. kandidat. Rutesvar caches pr. mål og 10 m-
område i 30 s (max 2000 poster); langsomme rutetjek logges. Æg: 'ingen mere last' markerer nu kilden som
hvilende 3 min, så runden roterer mellem hønsehusene.
This commit is contained in:
2026-09-26 11:07:16 +02:00
parent 038cb5be54
commit 0fca6e8a9a
8 changed files with 138 additions and 11 deletions
+14 -1
View File
@@ -25,6 +25,9 @@ ADOutbound.NOTIFICATION_MS = 8000
-- spawnet, forkert farm, ...): kilden udelukkes for varen i EMPTY_SOURCE_TTL_MS og turen afsluttes.
ADOutbound.EMPTY_SOURCE_MS = 30000
ADOutbound.EMPTY_SOURCE_TTL_MS = 300000
-- kilde der gav lidt og så intet mere (fx paller uden for Universal Autoloads rækkevidde): hviler så længe,
-- så de andre kilder kommer til (in-game 26/9: æg-vognen kørte til samme hønsehus tre gange i træk)
ADOutbound.THIN_SOURCE_REST_MS = 180000
-- Autoload-bil på vej til aflæsning: stropperne løsnes så mange meter FØR markøren. Markøren står
-- hvor næsen stopper, og en lastbils lad har passeret salgstriggeren dér; AutoDrive løsner selv
-- først ved markøren ("AL unload = center"), hvilket er for sent for en lastbil.
@@ -42,6 +45,11 @@ local warned = setmetatable({}, {__mode = "k"})
local emptyUntil = {}
local isInstalled = false
-- Glem alle "tom/hvilende kilde"-markeringer (tests; og når runs genindlæses).
function ADOutbound.resetEmptySources()
emptyUntil = {}
end
local function now()
if g_currentMission ~= nil and type(g_currentMission.time) == "number" then
return g_currentMission.time
@@ -753,7 +761,12 @@ function ADOutbound.beforeLoadUpdate(adEnv, task, dt)
return true
end
if state.noProgressMs > ADOutbound.NO_PROGRESS_MS and level > 0 and not spawnPending then
Logging.info(ADOutbound.LOG_PREFIX .. "'%s': ingen mere last ved %s; kører med %.0f l", tostring(ADRuns.vehicleLabel(vehicle)), tostring(source ~= nil and source.name or state.current), level)
local rests = now() + ADOutbound.THIN_SOURCE_REST_MS
for _, fillType in ipairs(state.trip.fillTypes) do
local key = tostring(state.current) .. ":" .. tostring(fillType)
if emptyUntil[key] == nil or emptyUntil[key] < rests then emptyUntil[key] = rests end
end
Logging.info(ADOutbound.LOG_PREFIX .. "'%s': ingen mere last ved %s; kører med %.0f l (kilden hviler %d min, så de andre kommer til)", tostring(ADRuns.vehicleLabel(vehicle)), tostring(source ~= nil and source.name or state.current), level, math.floor(ADOutbound.THIN_SOURCE_REST_MS / 60000))
state.noProgressMs, state.completed = 0, true
task:finished()
return true
+68 -5
View File
@@ -124,11 +124,42 @@ local function graphReaches(adEnv, vehicle, targetId)
return false
end
function ADWaitPool.hasRouteTo(adEnv, vehicle, wayPointId)
local graph = adEnv.ADGraphManager
if graph.getPathTo == nil then
return true
-- Rutesvar gemmes ROUTE_CACHE_MS pr. mål og 10 m-område: holdende vogne spørger hvert 5. s for hver
-- kandidat, og AD's stifinding (+ reserve-søgningen) gennem hele vejnettet gav et hak hvert 5. s
-- (in-game 26/9). Vejnettet ændrer sig ikke så hurtigt.
ADWaitPool.ROUTE_CACHE_MS = 30000
ADWaitPool.ROUTE_CELL_M = 10
ADWaitPool.SLOW_ROUTE_MS = 3
local routeCache = {}
local routeCacheSize = 0
ADWaitPool.ROUTE_CACHE_MAX = 2000
local function remember(key, result, at)
if routeCache[key] == nil then
routeCacheSize = routeCacheSize + 1
if routeCacheSize > ADWaitPool.ROUTE_CACHE_MAX then
routeCache, routeCacheSize = {}, 1
end
end
routeCache[key] = {result = result, at = at}
end
local function clockMs()
local ok, ms = pcall(function() return netGetTime() end)
if ok and type(ms) == "number" then return ms end
return nil
end
local function routeKey(vehicle, wayPointId)
if vehicle.rootNode == nil or getWorldTranslation == nil then return nil end
local ok, x, _, z = pcall(getWorldTranslation, vehicle.rootNode)
if not ok or x == nil then return nil end
local cell = ADWaitPool.ROUTE_CELL_M
return string.format("%s:%d:%d", tostring(wayPointId), math.floor(x / cell), math.floor(z / cell))
end
local function computeRoute(adEnv, vehicle, wayPointId)
local graph = adEnv.ADGraphManager
if pathReaches(graph:getPathTo(vehicle, wayPointId), wayPointId) then
return true
end
@@ -142,13 +173,45 @@ function ADWaitPool.hasRouteTo(adEnv, vehicle, wayPointId)
return false
end
function ADWaitPool.hasRouteTo(adEnv, vehicle, wayPointId)
local graph = adEnv.ADGraphManager
if graph.getPathTo == nil then
return true
end
local now = clockMs()
local key = now ~= nil and routeKey(vehicle, wayPointId) or nil
local cached = key ~= nil and routeCache[key] or nil
if cached ~= nil and now - cached.at < ADWaitPool.ROUTE_CACHE_MS then
return cached.result
end
local result = computeRoute(adEnv, vehicle, wayPointId)
if key ~= nil then
local spent = (clockMs() or now) - now
remember(key, result, now)
if spent > ADWaitPool.SLOW_ROUTE_MS and Logging ~= nil and Logging.info ~= nil
and (ADWaitPool.lastSlowLog == nil or now - ADWaitPool.lastSlowLog > 60000) then
ADWaitPool.lastSlowLog = now
Logging.info("ADSmartPickup: rutetjek til markør %s tog %.1f ms (%s) — gemmes nu i %d s", tostring(wayPointId), spent, result and "vej" or "ingen vej", ADWaitPool.ROUTE_CACHE_MS / 1000)
end
end
return result
end
function ADWaitPool.hasRouteBothWays(adEnv, vehicle, toWayPointId, homeWayPointId)
local graph = adEnv.ADGraphManager
if graph.getPathTo == nil or graph.pathFromTo == nil then
return true
end
return pathReaches(graph:getPathTo(vehicle, toWayPointId), toWayPointId)
local now = clockMs()
local key = now ~= nil and routeKey(vehicle, tostring(toWayPointId) .. ">" .. tostring(homeWayPointId)) or nil
local cached = key ~= nil and routeCache[key] or nil
if cached ~= nil and now - cached.at < ADWaitPool.ROUTE_CACHE_MS then
return cached.result
end
local result = pathReaches(graph:getPathTo(vehicle, toWayPointId), toWayPointId)
and pathReaches(graph:pathFromTo(toWayPointId, homeWayPointId), homeWayPointId)
if key ~= nil then remember(key, result, now) end
return result
end
-- Står AD midt i en (blokeret) af-/pålæsning, stoppes den pænt først — ellers kører
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<modDesc descVersion="107">
<author>masterdraco</author>
<version>1.27.2.0</version>
<version>1.27.3.0</version>
<title>
<en>AD Smart Pickup</en>
</title>