fix(marker): påfyldning finder selv læssestation m. varen og AD-markør (AD's automaticPickupTarget er slået fra); tom sæt = ikke færdig; 30 s backoff når sæt mangler

Review-fund 26/9 (CRITICAL): setAutomaticPickupTarget er no-op i AutoDrive (AutoDrive.automaticPickupTarget = false),
så LOAD-mode ville køre til F-markøren og hænge. (MEDIUM): ingen backoff ved manglende sæt.
This commit is contained in:
2026-09-26 00:13:01 +02:00
parent b1a65929a7
commit 944e61d1a8
3 changed files with 69 additions and 12 deletions
+49 -8
View File
@@ -13,6 +13,9 @@ ADFieldWork.COURSE_WAIT_MS = 180000
ADFieldWork.PLAYER_DRIVING_KMH = 3
-- riven skal være udfoldet og i gang, før nedlægningsområdet måles
ADFieldWork.WINDROW_MEASURE_MS = 10000
-- mangler der sæt, prøves igen efter så lang tid (ikke hvert sekund over hele flåden)
ADFieldWork.NO_RIG_RETRY_MS = 30000
ADFieldWork.REFILL_ROLES = {seeder = true, fertilizer = true, limer = true, weeder = true}
local function log(...) ADFieldJobs.log(...) end
local function note(...) ADFieldJobs.note(...) end
@@ -298,7 +301,7 @@ function ADFieldWork.dispatch(adEnv, field, info, decision)
rigs = rig ~= nil and {rig} or nil
end
if rigs == nil then
note(field.id, {reason = {key = "spu_field_reason_" .. tostring(why), role = role, args = args}})
note(field.id, {reason = {key = "spu_field_reason_" .. tostring(why), role = role, args = args}, retryAt = now() + ADFieldWork.NO_RIG_RETRY_MS})
return
end
local count = #rigs
@@ -340,19 +343,50 @@ local function prepareCollector(adEnv, field, info, assignment)
return true
end
-- Påfyldning undervejs (såmaskine/sprøjte/spreder): AutoDrive LOAD med automatisk påfyldningsmål og
-- hjælper = Courseplay. Når CP melder tom (onCpEmpty), kører AD til nærmeste påfyldning af varen, fylder
-- op, kører tilbage til F-markøren og genstarter CP. Courseplay og AutoDrive er bygget til netop dette.
-- Nærmeste påfyldning af varen: en læssestation gården har adgang til, med varen på lager, en AutoDrive-
-- markør ved triggeren og vej fra traktoren. (AutoDrives eget "automatiske påfyldningsmål" er slået fra i
-- AutoDrive — AutoDrive.automaticPickupTarget = false — så vi finder stedet selv, som silovalget.)
function ADFieldWork.findRefillMarker(adEnv, vehicle, fillType, x, z)
local farmId = vehicle:getOwnerFarmId()
local best, bestDistance = nil, math.huge
local ok = pcall(function()
for _, station in pairs(g_currentMission.storageSystem:getLoadingStations()) do
local supported = station.getAISupportedFillTypes ~= nil and station:getAISupportedFillTypes() or {}
if g_currentMission.accessHandler:canFarmAccess(farmId, station) and supported[fillType]
and (station:getFillLevel(fillType, farmId) or 0) > 0 then
local wayPointId = adEnv.ADTriggerManager:getMarkerAtStation(station, vehicle, 10)
local wayPoint = wayPointId ~= nil and wayPointId > 0 and adEnv.ADGraphManager:getWayPointById(wayPointId) or nil
if wayPoint ~= nil then
local distance = (wayPoint.x - x) ^ 2 + (wayPoint.z - z) ^ 2
if distance < bestDistance and ADUnloadWait.hasRouteTo(adEnv, vehicle, wayPointId) then
best, bestDistance = wayPointId, distance
end
end
end
end
end)
return ok and best or nil
end
-- Påfyldning undervejs (såmaskine/sprøjte/spreder): AutoDrive LOAD med hjælper = Courseplay. Når CP melder
-- tom (onCpEmpty), kører AD til påfyldningen (2. markør), fylder op, kører tilbage til F-markøren (1. markør)
-- og genstarter CP. Findes ingen påfyldning, stopper sættet når det er tomt ("tom for …", se finish).
local function prepareRefill(adEnv, field, info, assignment)
local vehicle = assignment.vehicle
local fillType = ADCpBridge.getRefillFillType(vehicle)
if fillType == nil then return end
assignment.refillFillType = fillType
local name = g_fillTypeManager ~= nil and g_fillTypeManager:getFillTypeNameByIndex(fillType) or tostring(fillType)
local refillId = ADFieldWork.findRefillMarker(adEnv, vehicle, fillType, info.x, info.z)
if refillId == nil then
log(field.id, "ingen påfyldning af %s med AutoDrive-markør fundet — '%s' stopper når den er tom", tostring(name), ADRuns.vehicleLabel(vehicle))
return
end
local module = stateModule(vehicle)
local ok = pcall(function()
module:setMode(adEnv.AutoDrive.MODE_LOAD)
module:setFirstMarkerByWayPointId(info.markerId)
module:setSecondMarkerByWayPointId(info.markerId)
module:setAutomaticPickupTarget(true)
module:setSecondMarkerByWayPointId(refillId)
module:setFillType(fillType)
module:setStartHelper(true)
module.usedHelper = helperCp(adEnv)
@@ -361,8 +395,8 @@ local function prepareRefill(adEnv, field, info, assignment)
end)
if ok then
assignment.adHandlesEnd = true
local name = g_fillTypeManager ~= nil and g_fillTypeManager:getFillTypeNameByIndex(fillType) or tostring(fillType)
log(field.id, "'%s' fyldes op med %s af AutoDrive når den er tom", ADRuns.vehicleLabel(vehicle), tostring(name))
local marker = adEnv.ADGraphManager:getMapMarkerByWayPointId(refillId)
log(field.id, "'%s' fyldes op med %s ved %s af AutoDrive når den er tom", ADRuns.vehicleLabel(vehicle), tostring(name), tostring(marker ~= nil and marker.name or refillId))
end
end
@@ -493,6 +527,13 @@ end
-- Sættet er færdigt: rest til lager (læsse-/aflæsningsvogn), ellers parkering.
local function finishAssignment(adEnv, assignment)
local vehicle = assignment.vehicle
-- tom såmaskine/sprøjte der ikke blev fyldt op: arbejdet er IKKE færdigt — marken må ikke gå videre
if assignment.refillFillType ~= nil and ADCpBridge.getRefillLevel(vehicle, assignment.refillFillType) <= 0 then
local name = g_fillTypeManager ~= nil and g_fillTypeManager:getFillTypeNameByIndex(assignment.refillFillType) or "?"
ADFieldWork.release(assignment)
fail(assignment.fieldId, string.format("'%s' er tom for %s — fyld op, så fortsætter marken", ADRuns.vehicleLabel(vehicle), tostring(name)))
return
end
log(assignment.fieldId, "%s '%s' færdig", assignment.role, ADRuns.vehicleLabel(vehicle))
-- læssevogn/påfyldte sæt parkeres af AutoDrive selv (onCpFinished med parkering sat)
local park = not assignment.adHandlesEnd and parkMarkerId(adEnv, vehicle) or nil