fix: silo til forkert last kræver kun vejnet fra traktoren (ikke silo→mål); advarsel forklarer hvorfor ingen silo (v1.11.8.0)

This commit is contained in:
2026-09-23 02:30:51 +02:00
parent ce32eb8e44
commit 0abf282877
5 changed files with 46 additions and 21 deletions
+18 -7
View File
@@ -41,19 +41,24 @@ local function acceptsRest(station, fillType, rest, farmId)
end end
-- Nærmeste silo med plads til resten og vejnet til/fra; siloer der allerede har varen foretrækkes. -- Nærmeste silo med plads til resten og vejnet til/fra; siloer der allerede har varen foretrækkes.
-- Nærmeste silo med plads til resten og vejnet fra traktoren; siloer der allerede har varen
-- foretrækkes. Returnerer marker — eller nil + en forklaring (til loggen).
function ADLoadSwap.findDumpMarker(adEnv, vehicle, fillType, rest, homeWayPointId, isReachable) function ADLoadSwap.findDumpMarker(adEnv, vehicle, fillType, rest, homeWayPointId, isReachable)
if vehicle.rootNode == nil then if vehicle.rootNode == nil then
return nil return nil, "køretøjet har ingen position"
end end
local farmId = ADSmartPickup.getFarmId(vehicle) local farmId = ADSmartPickup.getFarmId(vehicle)
local homeStation = ADSmartPickup.getUnloadStationAtWayPointId(adEnv, homeWayPointId, farmId) local homeStation = homeWayPointId ~= nil and ADSmartPickup.getUnloadStationAtWayPointId(adEnv, homeWayPointId, farmId) or nil
local x, _, z = getWorldTranslation(vehicle.rootNode) local x, _, z = getWorldTranslation(vehicle.rootNode)
local candidates = {} local candidates = {}
local silos, withSpace = 0, 0
for _, marker in pairs(adEnv.ADGraphManager:getMapMarkers()) do for _, marker in pairs(adEnv.ADGraphManager:getMapMarkers()) do
local station = ADSmartPickup.getUnloadStationAtWayPointId(adEnv, marker.id, farmId) local station = ADSmartPickup.getUnloadStationAtWayPointId(adEnv, marker.id, farmId)
if station ~= nil and isSilo(station, homeStation) and acceptsRest(station, fillType, rest, farmId) then if station ~= nil and isSilo(station, homeStation) then
silos = silos + 1
if acceptsRest(station, fillType, rest, farmId) then
withSpace = withSpace + 1
local wayPoint = adEnv.ADGraphManager:getWayPointById(marker.id) local wayPoint = adEnv.ADGraphManager:getWayPointById(marker.id)
-- En markør uden waypoint (stale AD-graf) skal springes over, ikke crashe hele opslaget.
if wayPoint ~= nil then if wayPoint ~= nil then
local dx, dz = wayPoint.x - x, wayPoint.z - z local dx, dz = wayPoint.x - x, wayPoint.z - z
table.insert(candidates, { table.insert(candidates, {
@@ -64,6 +69,7 @@ function ADLoadSwap.findDumpMarker(adEnv, vehicle, fillType, rest, homeWayPointI
end end
end end
end end
end
table.sort(candidates, function(a, b) table.sort(candidates, function(a, b)
if a.hasFillType ~= b.hasFillType then if a.hasFillType ~= b.hasFillType then
return a.hasFillType return a.hasFillType
@@ -75,7 +81,12 @@ function ADLoadSwap.findDumpMarker(adEnv, vehicle, fillType, rest, homeWayPointI
return candidate.marker return candidate.marker
end end
end end
return nil if silos == 0 then
return nil, "ingen silo med aflæsningsmarkør fundet (siloen skal have en AD-markør ved aflæsningstriggeren)"
elseif withSpace == 0 then
return nil, string.format("%d silo(er) fundet, men ingen tager varen med plads til %.0f l", silos, rest)
end
return nil, string.format("%d silo(er) tager varen, men AutoDrive finder ingen rute fra traktoren til dem", withSpace)
end end
-- Kaldes fra Wait-logikken hvert tick; redirect(task, id) og release(vehicle) er dens egne. -- Kaldes fra Wait-logikken hvert tick; redirect(task, id) og release(vehicle) er dens egne.
@@ -92,13 +103,13 @@ function ADLoadSwap.tryFromWait(adEnv, task, wait, dt, redirect, release, isReac
if missing == nil and not wait.isRejected then if missing == nil and not wait.isRejected then
return false return false
end end
local marker = ADLoadSwap.findDumpMarker(adEnv, vehicle, wait.fillType, wait.rest, wait.homeDestinationID, isReachable) local marker, why = ADLoadSwap.findDumpMarker(adEnv, vehicle, wait.fillType, wait.rest, wait.homeDestinationID, isReachable)
local restName = g_fillTypeManager ~= nil and g_fillTypeManager:getFillTypeNameByIndex(wait.fillType) or tostring(wait.fillType) local restName = g_fillTypeManager ~= nil and g_fillTypeManager:getFillTypeNameByIndex(wait.fillType) or tostring(wait.fillType)
local missingName = missing ~= nil and (g_fillTypeManager ~= nil and g_fillTypeManager:getFillTypeNameByIndex(missing.fillType) or tostring(missing.fillType)) or "-" local missingName = missing ~= nil and (g_fillTypeManager ~= nil and g_fillTypeManager:getFillTypeNameByIndex(missing.fillType) or tostring(missing.fillType)) or "-"
if marker == nil then if marker == nil then
if not warnedNoSilo[vehicle] then if not warnedNoSilo[vehicle] then
warnedNoSilo[vehicle] = true warnedNoSilo[vehicle] = true
Logging.warning(ADLoadSwap.LOG_PREFIX .. "'%s' venter med %.0f l %s, og målet mangler %s — ingen silo med plads og vejnet til/fra tager resten, så den bliver ved Wait-punktet", tostring(vehicle:getName()), wait.rest, tostring(restName), tostring(missingName)) Logging.warning(ADLoadSwap.LOG_PREFIX .. "'%s' venter med %.0f l %s (%s) — %s; den bliver ved Wait-punktet", tostring(vehicle:getName()), wait.rest, tostring(restName), missing ~= nil and ("målet mangler " .. tostring(missingName)) or "målet tager ikke varen", tostring(why))
end end
return false return false
end end
+3 -3
View File
@@ -327,12 +327,12 @@ function ADRunsController.findWrongCargoDump(adEnv, run, vehicle, targetId)
end end
end end
local isReachable = function(markerId) local isReachable = function(markerId)
return ADUnloadWait.hasRouteBothWays == nil or ADUnloadWait.hasRouteBothWays(adEnv, vehicle, markerId, targetId) return ADUnloadWait.hasRouteTo == nil or ADUnloadWait.hasRouteTo(adEnv, vehicle, markerId)
end end
local marker = ADLoadSwap.findDumpMarker(adEnv, vehicle, fillType, liters, targetId, isReachable) local marker, why = ADLoadSwap.findDumpMarker(adEnv, vehicle, fillType, liters, targetId, isReachable)
local fillTypeName = g_fillTypeManager ~= nil and g_fillTypeManager:getFillTypeNameByIndex(fillType) or tostring(fillType) local fillTypeName = g_fillTypeManager ~= nil and g_fillTypeManager:getFillTypeNameByIndex(fillType) or tostring(fillType)
if marker == nil then if marker == nil then
Logging.warning(ADRunsController.LOG_PREFIX .. "run '%s': '%s' har %.0f l %s på vognen, som målet ikke tager, og ingen silo med plads/vejnet tager den — AutoDrive starter som normalt", tostring(run.name), tostring(vehicle:getName()), liters, tostring(fillTypeName)) Logging.warning(ADRunsController.LOG_PREFIX .. "run '%s': '%s' har %.0f l %s på vognen, som målet ikke tager — %s; AutoDrive starter som normalt", tostring(run.name), tostring(vehicle:getName()), liters, tostring(fillTypeName), tostring(why))
return nil return nil
end end
Logging.info(ADRunsController.LOG_PREFIX .. "run '%s': '%s' læsser først %.0f l %s af i %s (markør %s) — målet tager ikke varen", tostring(run.name), tostring(vehicle:getName()), liters, tostring(fillTypeName), tostring(marker.name), tostring(marker.markerIndex or marker.id)) Logging.info(ADRunsController.LOG_PREFIX .. "run '%s': '%s' læsser først %.0f l %s af i %s (markør %s) — målet tager ikke varen", tostring(run.name), tostring(vehicle:getName()), liters, tostring(fillTypeName), tostring(marker.name), tostring(marker.markerIndex or marker.id))
+15 -1
View File
@@ -75,6 +75,16 @@ end
-- Findes der vejnet fra køretøjet til Wait-punktet OG fra Wait-punktet hjem til målet? -- 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. -- Sendes AutoDrive mod et punkt uden rute, viser den "cannot reach" og slukker sig selv.
-- getPathTo/pathFromTo er rene opslag uden bivirkninger. -- 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.
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)
end
local function hasRouteBothWays(adEnv, vehicle, waitWayPointId, homeWayPointId) local function hasRouteBothWays(adEnv, vehicle, waitWayPointId, homeWayPointId)
local graph = adEnv.ADGraphManager local graph = adEnv.ADGraphManager
if graph.getPathTo == nil or graph.pathFromTo == nil then if graph.getPathTo == nil or graph.pathFromTo == nil then
@@ -185,7 +195,7 @@ local function updateWaiting(adEnv, task, wait, dt)
if free == nil or not ADSupplyPlanner.canUnloadRest(free, rest, capacity, freeFraction) then if free == nil or not ADSupplyPlanner.canUnloadRest(free, rest, capacity, freeFraction) then
if ADLoadSwap ~= nil then if ADLoadSwap ~= nil then
local isReachable = function(markerId) local isReachable = function(markerId)
return hasRouteBothWays(adEnv, vehicle, markerId, wait.homeDestinationID) return hasRouteTo(adEnv, vehicle, markerId)
end end
ADLoadSwap.tryFromWait(adEnv, task, wait, dt, redirect, release, isReachable) ADLoadSwap.tryFromWait(adEnv, task, wait, dt, redirect, release, isReachable)
end end
@@ -222,6 +232,10 @@ function ADUnloadWait.hasRouteBothWays(adEnv, vehicle, toWayPointId, homeWayPoin
return hasRouteBothWays(adEnv, vehicle, toWayPointId, homeWayPointId) return hasRouteBothWays(adEnv, vehicle, toWayPointId, homeWayPointId)
end end
function ADUnloadWait.hasRouteTo(adEnv, vehicle, wayPointId)
return hasRouteTo(adEnv, vehicle, wayPointId)
end
function ADUnloadWait.getRestLoad(adEnv, vehicle) function ADUnloadWait.getRestLoad(adEnv, vehicle)
return getRestLoad(adEnv, vehicle) return getRestLoad(adEnv, vehicle)
end end
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?> <?xml version="1.0" encoding="utf-8" standalone="no"?>
<modDesc descVersion="107"> <modDesc descVersion="107">
<author>masterdraco</author> <author>masterdraco</author>
<version>1.11.7.0</version> <version>1.11.8.0</version>
<title> <title>
<en>AD Smart Pickup</en> <en>AD Smart Pickup</en>
</title> </title>
+1 -1
View File
@@ -848,7 +848,7 @@ local mark3 = #logLines
UnloadTask.update(st3, ADLoadSwap.CHECK_INTERVAL_MS + 1) UnloadTask.update(st3, ADLoadSwap.CHECK_INTERVAL_MS + 1)
UnloadTask.update(st3, ADLoadSwap.CHECK_INTERVAL_MS + 1) UnloadTask.update(st3, ADLoadSwap.CHECK_INTERVAL_MS + 1)
check("S3 bliver ved Wait", st3.destinationID, 40) check("S3 bliver ved Wait", st3.destinationID, 40)
check("S3 én advarsel", countLogsSince(mark3, "ingen silo"), 1) check("S3 én advarsel", countLogsSince(mark3, "bliver ved Wait-punktet"), 1)
-- S4: silo uden vejnet hjem springes over -- S4: silo uden vejnet hjem springes over
buildSwapWorld() buildSwapWorld()