fix(marksilo): tom silo — lånt vogn med last ved en tom marksilo kører resten til fabrik (plads til hele resten) ellers gårdlager; AD-ture fra marksiloer overtages igen efter genindlæsning (v1.50.4.0)
This commit is contained in:
@@ -45,6 +45,20 @@ local function chooseStore(stores, silo, fillType, liters, minLiters, reserved,
|
||||
return best or most
|
||||
end
|
||||
|
||||
-- Tom silo: en lånt vogn med last, der har stået stille ved en tom marksilo i REST_IDLE_MS, kører resten videre
|
||||
-- (AutoDrive venter ellers til vognen er fuld). s = {atSilo, stillMs, siloStock, cargo}
|
||||
ADFieldSiloPlanner.REST_IDLE_MS = 30000
|
||||
ADFieldSiloPlanner.REST_MIN_LITERS = 100
|
||||
function ADFieldSiloPlanner.restDue(s)
|
||||
return s.atSilo == true and (s.stillMs or 0) >= ADFieldSiloPlanner.REST_IDLE_MS
|
||||
and (s.cargo or 0) >= ADFieldSiloPlanner.REST_MIN_LITERS and (s.siloStock or 0) < ADFieldSiloPlanner.REST_MIN_LITERS
|
||||
end
|
||||
|
||||
-- Lager til en rest: fabrik kun med plads til hele resten, ellers gårdlager (nærmeste med plads, ellers mest plads).
|
||||
function ADFieldSiloPlanner.restStore(stores, silo, fillType, liters)
|
||||
return chooseStore(stores, silo, fillType, liters, 1, {}, true) or chooseStore(stores, silo, fillType, liters, 1, {}, false)
|
||||
end
|
||||
|
||||
local function canCarry(vehicle, fillType)
|
||||
if (vehicle.capacity or 0) <= 0 then return false end
|
||||
if vehicle.cargo ~= nil and vehicle.cargo ~= fillType then return false end
|
||||
|
||||
@@ -17,6 +17,7 @@ ADFieldSilos.CARGO_MIN_LITERS = 100 -- rest under dette tæller ikke som last
|
||||
ADFieldSilos.FARM_RADIUS = 100
|
||||
-- Siloer højst så langt fra en nabo hører til samme klynge (Farma-rækker: 15 m mellem siloer, 18 m mellem rækker)
|
||||
ADFieldSilos.CLUSTER_LINK = 60
|
||||
ADFieldSilos.REST_SILO_DISTANCE = 40 -- m fra marksiloens markør: vognen holder ved siloen
|
||||
ADFieldSilos.FETCH_TIMEOUT_MS = 300000 -- så længe må en traktor være om at hente en puljevogn
|
||||
ADFieldSilos.MOVING_SPEED = 0.00028 -- m/ms, samme grænse som AutoDrive
|
||||
ADFieldSilos.FILE_NAME = "ADSmartPickup_fieldsilos.xml"
|
||||
@@ -440,6 +441,66 @@ function ADFieldSilos.stopAll(adEnv)
|
||||
for _, vehicle in ipairs(list) do release(adEnv, vehicle, "stopped") end
|
||||
end
|
||||
|
||||
-- Efter genindlæsning genoptager AutoDrive selv "Hent og aflever" fra marksiloerne, men lånene er glemt: sådanne
|
||||
-- vogne overtages igen som lån (tæller i "højst x ude", og tom silo-vagten gælder).
|
||||
function ADFieldSilos.adoptOrphans(adEnv, silos)
|
||||
local byMarker = {}
|
||||
for _, silo in ipairs(silos or {}) do
|
||||
if silo.markerId ~= nil then byMarker[silo.markerId] = silo end
|
||||
end
|
||||
for _, vehicle in ipairs(ADRunsController.getFarmVehicles(adEnv)) do
|
||||
local module = vehicle.ad ~= nil and vehicle.ad.stateModule or nil
|
||||
if loans[vehicle] == nil and module ~= nil and module:isActive() and module:getMode() == adEnv.AutoDrive.MODE_PICKUPANDDELIVER then
|
||||
local first = module:getFirstMarker()
|
||||
local silo = first ~= nil and byMarker[first.id] or nil
|
||||
if silo ~= nil then
|
||||
local fillType = module.getFillType ~= nil and module:getFillType() or nil
|
||||
loans[vehicle] = {siloId = silo.id, siloName = silo.name, fillType = fillType, liters = 0, startedMs = nowMs,
|
||||
lastProgressMs = nowMs, lastFill = fillLevel(adEnv, vehicle), hasProgressed = true, adopted = true}
|
||||
Logging.info(ADFieldSilos.LOG_PREFIX .. "'%s' overtaget igen (AutoDrive kører fra %s efter genindlæsning)",
|
||||
tostring(ADRuns.vehicleLabel(vehicle)), tostring(silo.name))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Tom silo-vagt: en lånt vogn med last, der står stille ved en tom marksilo, kører resten videre — til en fabrik
|
||||
-- med plads til hele resten, ellers til et gårdlager (AutoDrive venter ellers til vognen er fuld).
|
||||
local warnedNoRestStore = {}
|
||||
local function checkRest(adEnv, vehicle, loan, moving, fill)
|
||||
if loan.delivering or loan.fetching then return end
|
||||
local silo = nil
|
||||
for _, candidate in ipairs(ADFieldSilos.lastSilos or {}) do
|
||||
if candidate.id == loan.siloId then silo = candidate end
|
||||
end
|
||||
local wayPoint = silo ~= nil and silo.markerId ~= nil and adEnv.ADGraphManager:getWayPointById(silo.markerId) or nil
|
||||
if wayPoint == nil or vehicle.rootNode == nil then return end
|
||||
local x, _, z = getWorldTranslation(vehicle.rootNode)
|
||||
local atSilo = (x - wayPoint.x) ^ 2 + (z - wayPoint.z) ^ 2 <= ADFieldSilos.REST_SILO_DISTANCE ^ 2
|
||||
if moving or not atSilo then loan.stillSince = nil return end
|
||||
loan.stillSince = loan.stillSince or nowMs
|
||||
local state = {atSilo = atSilo, stillMs = nowMs - loan.stillSince,
|
||||
siloStock = (silo.stock or {})[loan.fillType] or 0, cargo = fill}
|
||||
if not ADFieldSiloPlanner.restDue(state) then return end
|
||||
local store = ADFieldSiloPlanner.restStore(ADFieldSilos.lastStores, silo, loan.fillType, fill)
|
||||
if store == nil then
|
||||
if not warnedNoRestStore[vehicle] then
|
||||
warnedNoRestStore[vehicle] = true
|
||||
Logging.warning(ADFieldSilos.LOG_PREFIX .. "'%s' har %d l %s fra tom %s, men intet lager har plads",
|
||||
tostring(ADRuns.vehicleLabel(vehicle)), math.floor(fill), fillTypeName(loan.fillType), tostring(silo.name))
|
||||
end
|
||||
return
|
||||
end
|
||||
warnedNoRestStore[vehicle] = nil
|
||||
loan.delivering = true
|
||||
loan.startedMs, loan.hasProgressed = nowMs, true
|
||||
local isPool = ADHitch ~= nil and #ADHitch.poolParkIds(adEnv, vehicle) > 0
|
||||
if not isPool then ADFieldWork.enableParkAtJobFinished(vehicle) end
|
||||
ADFieldWork.startAd(adEnv, vehicle, adEnv.AutoDrive.MODE_DELIVERTO, store.markerId, nil, loan.fillType)
|
||||
Logging.info(ADFieldSilos.LOG_PREFIX .. "'%s': %s er tom — kører resten (%d l %s) til %s",
|
||||
tostring(ADRuns.vehicleLabel(vehicle)), tostring(silo.name), math.floor(fill), fillTypeName(loan.fillType), tostring(store.name))
|
||||
end
|
||||
|
||||
local function checkLoans(adEnv)
|
||||
local list = {}
|
||||
for vehicle in pairs(loans) do table.insert(list, vehicle) end
|
||||
@@ -467,6 +528,9 @@ local function checkLoans(adEnv)
|
||||
controlled = vehicle.getIsControlled ~= nil and vehicle:getIsControlled() or false,
|
||||
fill = fill, moving = (vehicle.lastSpeedReal or 0) >= ADFieldSilos.MOVING_SPEED,
|
||||
}
|
||||
checkRest(adEnv, vehicle, loan, vehicleState.moving, fill)
|
||||
if loans[vehicle] ~= loan then return end
|
||||
vehicleState.adActive = stateModule ~= nil and stateModule:isActive()
|
||||
local reason = ADFieldSilos.releaseReason(loan, vehicleState, nowMs)
|
||||
if vehicleState.moving or fill ~= (loan.lastFill or 0) then loan.hasProgressed = true end
|
||||
loan.lastFill = fill
|
||||
@@ -511,6 +575,11 @@ end
|
||||
function ADFieldSilos.planNow(adEnv)
|
||||
local cfg = ADFieldSilos.config
|
||||
local silos, stores, byId = ADFieldSilos.collectBuildings(adEnv)
|
||||
ADFieldSilos.lastSilos, ADFieldSilos.lastStores = silos, stores
|
||||
if cfg.enabled then
|
||||
local okAdopt, errAdopt = pcall(ADFieldSilos.adoptOrphans, adEnv, silos)
|
||||
if not okAdopt then Logging.warning(ADFieldSilos.LOG_PREFIX .. "overtagelse efter genindlæsning fejlede: %s", tostring(errAdopt)) end
|
||||
end
|
||||
local vehicles, vehiclesById, poolById = ADFieldSilos.collectVehicles(adEnv)
|
||||
local feedReserve, farmStock = nil, nil
|
||||
if cfg.toProduction then
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<modDesc descVersion="107">
|
||||
<author>masterdraco</author>
|
||||
<version>1.50.3.0</version>
|
||||
<version>1.50.4.0</version>
|
||||
<title>
|
||||
<en>AD Smart Pickup</en>
|
||||
</title>
|
||||
|
||||
Reference in New Issue
Block a user