diff --git a/FS25_ADSmartPickup/adLoadSwap.lua b/FS25_ADSmartPickup/adLoadSwap.lua index 9e5aa33..162159d 100644 --- a/FS25_ADSmartPickup/adLoadSwap.lua +++ b/FS25_ADSmartPickup/adLoadSwap.lua @@ -41,26 +41,32 @@ local function acceptsRest(station, fillType, rest, farmId) 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 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) if vehicle.rootNode == nil then - return nil + return nil, "køretøjet har ingen position" end 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 candidates = {} + local silos, withSpace = 0, 0 for _, marker in pairs(adEnv.ADGraphManager:getMapMarkers()) do local station = ADSmartPickup.getUnloadStationAtWayPointId(adEnv, marker.id, farmId) - if station ~= nil and isSilo(station, homeStation) and acceptsRest(station, fillType, rest, farmId) then - 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 - local dx, dz = wayPoint.x - x, wayPoint.z - z - table.insert(candidates, { - marker = marker, - hasFillType = ADSmartPickup.getOwnStorageLevel(station, {fillType}) > 0, - distance = dx * dx + dz * dz, - }) + 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) + if wayPoint ~= nil then + local dx, dz = wayPoint.x - x, wayPoint.z - z + table.insert(candidates, { + marker = marker, + hasFillType = ADSmartPickup.getOwnStorageLevel(station, {fillType}) > 0, + distance = dx * dx + dz * dz, + }) + end end end end @@ -75,7 +81,12 @@ function ADLoadSwap.findDumpMarker(adEnv, vehicle, fillType, rest, homeWayPointI return candidate.marker 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 -- 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 return false 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 missingName = missing ~= nil and (g_fillTypeManager ~= nil and g_fillTypeManager:getFillTypeNameByIndex(missing.fillType) or tostring(missing.fillType)) or "-" if marker == nil then if not warnedNoSilo[vehicle] then 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 return false end diff --git a/FS25_ADSmartPickup/adRunsController.lua b/FS25_ADSmartPickup/adRunsController.lua index 2b3c491..9d6f1b3 100644 --- a/FS25_ADSmartPickup/adRunsController.lua +++ b/FS25_ADSmartPickup/adRunsController.lua @@ -327,12 +327,12 @@ function ADRunsController.findWrongCargoDump(adEnv, run, vehicle, targetId) end end 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 - 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) 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 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)) diff --git a/FS25_ADSmartPickup/adUnloadWait.lua b/FS25_ADSmartPickup/adUnloadWait.lua index eb09109..e6ab82f 100644 --- a/FS25_ADSmartPickup/adUnloadWait.lua +++ b/FS25_ADSmartPickup/adUnloadWait.lua @@ -75,6 +75,16 @@ 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. +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 graph = adEnv.ADGraphManager 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 ADLoadSwap ~= nil then local isReachable = function(markerId) - return hasRouteBothWays(adEnv, vehicle, markerId, wait.homeDestinationID) + return hasRouteTo(adEnv, vehicle, markerId) end ADLoadSwap.tryFromWait(adEnv, task, wait, dt, redirect, release, isReachable) end @@ -222,6 +232,10 @@ function ADUnloadWait.hasRouteBothWays(adEnv, vehicle, toWayPointId, homeWayPoin return hasRouteBothWays(adEnv, vehicle, toWayPointId, homeWayPointId) end +function ADUnloadWait.hasRouteTo(adEnv, vehicle, wayPointId) + return hasRouteTo(adEnv, vehicle, wayPointId) +end + function ADUnloadWait.getRestLoad(adEnv, vehicle) return getRestLoad(adEnv, vehicle) end diff --git a/FS25_ADSmartPickup/modDesc.xml b/FS25_ADSmartPickup/modDesc.xml index 6ead6fc..f4d77c5 100644 --- a/FS25_ADSmartPickup/modDesc.xml +++ b/FS25_ADSmartPickup/modDesc.xml @@ -1,7 +1,7 @@ masterdraco - 1.11.7.0 + 1.11.8.0 <en>AD Smart Pickup</en> diff --git a/tests/test_adSmartPickup.lua b/tests/test_adSmartPickup.lua index 6012d6e..174f16d 100644 --- a/tests/test_adSmartPickup.lua +++ b/tests/test_adSmartPickup.lua @@ -848,7 +848,7 @@ local mark3 = #logLines 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 é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 buildSwapWorld()