feat: diagnose når AD står ved LOAD-mål uden at fylde
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
-- AD Load Diag
|
||||
-- Diagnose når AutoDrive står ved et LOAD-mål uden at fylde (in-game 30/9: Fendt + MEGA-sprøjte ved "Market Price
|
||||
-- Liquid Fill Station"). AutoDrive fylder kun, når en fyldenhed står i triggerens boks (trigger.fillableObjects) og
|
||||
-- triggeren har varen. Efter REPORT_MS ved målet uden fremgang skrives én linje: markør, vare, og for hver vogn den
|
||||
-- nærmeste AD-læssetrigger (afstand, har varen?, står vognen i boksen?). Ingen indgreb — kun log.
|
||||
|
||||
ADLoadDiag = {}
|
||||
ADLoadDiag.LOG_PREFIX = "ADSmartPickup: pålæsning: "
|
||||
ADLoadDiag.REPORT_MS = 30000
|
||||
|
||||
-- ---- ren logik ----
|
||||
|
||||
-- state (pr. opgave), dt, reached (ved målet), level (liter på vognene) -> true når der skal rapporteres (én gang pr.
|
||||
-- ankomst). Fremgang eller kørsel nulstiller.
|
||||
function ADLoadDiag.tick(state, dt, reached, level)
|
||||
if not reached then
|
||||
state.ms, state.reported, state.level = 0, false, nil
|
||||
return false
|
||||
end
|
||||
if state.level == nil or level > state.level then
|
||||
state.level, state.ms = level, 0
|
||||
return false
|
||||
end
|
||||
state.ms = (state.ms or 0) + (dt or 0)
|
||||
if state.reported or state.ms < ADLoadDiag.REPORT_MS then return false end
|
||||
state.reported = true
|
||||
return true
|
||||
end
|
||||
|
||||
-- ---- spil ----
|
||||
|
||||
local function fillTypeName(fillType)
|
||||
return g_fillTypeManager ~= nil and fillType ~= nil and g_fillTypeManager:getFillTypeNameByIndex(fillType) or tostring(fillType)
|
||||
end
|
||||
|
||||
local function inBox(trigger, trailer)
|
||||
for key, entry in pairs(trigger.fillableObjects or {}) do
|
||||
if key == trailer or (type(entry) == "table" and entry.object == trailer) then return true end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function describeTrailer(adEnv, trailer, fillType)
|
||||
local node = trailer.components ~= nil and trailer.components[1] ~= nil and trailer.components[1].node or trailer.rootNode
|
||||
if node == nil then return nil end
|
||||
local tx, _, tz = getWorldTranslation(node)
|
||||
local nearest, nearestOk = nil, nil
|
||||
for _, trigger in pairs(adEnv.ADTriggerManager.getLoadTriggers() or {}) do
|
||||
local x, _, z = adEnv.ADTriggerManager.getTriggerPos(trigger)
|
||||
if x ~= nil and (x ~= 0 or z ~= 0) then
|
||||
local d = math.sqrt((x - tx) ^ 2 + (z - tz) ^ 2)
|
||||
local ok = adEnv.ADTriggerManager.triggerSupportsFillType(trigger, fillType)
|
||||
if nearest == nil or d < nearest.d then nearest = {d = d, ok = ok, trigger = trigger} end
|
||||
if ok and (nearestOk == nil or d < nearestOk.d) then nearestOk = {d = d, trigger = trigger} end
|
||||
end
|
||||
end
|
||||
local name = trailer.getName ~= nil and trailer:getName() or "?"
|
||||
local parts = {}
|
||||
if nearest ~= nil then
|
||||
table.insert(parts, string.format("nærmeste AD-trigger %.1f m (%s varen, %s)", nearest.d, nearest.ok and "har" or "UDEN",
|
||||
inBox(nearest.trigger, trailer) and "vognen i boksen" or "vognen IKKE i boksen"))
|
||||
end
|
||||
if nearestOk ~= nil and (nearest == nil or nearestOk.trigger ~= nearest.trigger) then
|
||||
table.insert(parts, string.format("nærmeste med varen %.1f m (%s)", nearestOk.d,
|
||||
inBox(nearestOk.trigger, trailer) and "i boksen" or "ikke i boksen"))
|
||||
end
|
||||
if nearestOk == nil then table.insert(parts, "INGEN AD-læssetrigger med varen") end
|
||||
return string.format("'%s': %s", tostring(name), table.concat(parts, ", "))
|
||||
end
|
||||
|
||||
local function report(adEnv, task)
|
||||
local vehicle = task.vehicle
|
||||
local fillType = vehicle.ad.stateModule.getFillType ~= nil and vehicle.ad.stateModule:getFillType() or nil
|
||||
local marker = task.destinationID ~= nil and adEnv.ADGraphManager:getMapMarkerByWayPointId(task.destinationID) or nil
|
||||
local lines = {}
|
||||
for _, trailer in ipairs(task.trailers or {}) do
|
||||
if trailer.getFillUnits ~= nil and #trailer:getFillUnits() > 0 then
|
||||
local ok, line = pcall(describeTrailer, adEnv, trailer, fillType)
|
||||
if ok and line ~= nil then table.insert(lines, line) end
|
||||
end
|
||||
end
|
||||
local maxDistance = adEnv.AutoDrive.getMaxTriggerDistance ~= nil and adEnv.AutoDrive.getMaxTriggerDistance(vehicle) or nil
|
||||
Logging.warning(ADLoadDiag.LOG_PREFIX .. "'%s' står ved '%s' uden at fylde %s i %d s (AD-triggerafstand %s m): %s",
|
||||
tostring(ADRuns.vehicleLabel(vehicle)), tostring(marker ~= nil and marker.name or task.destinationID), fillTypeName(fillType),
|
||||
math.floor(ADLoadDiag.REPORT_MS / 1000), tostring(maxDistance), #lines > 0 and table.concat(lines, "; ") or "ingen vogne med fyldenheder")
|
||||
end
|
||||
|
||||
local states = setmetatable({}, {__mode = "k"})
|
||||
|
||||
function ADLoadDiag.after(adEnv, task, dt)
|
||||
local vehicle = task.vehicle
|
||||
if vehicle == nil or vehicle.ad == nil or vehicle.ad.drivePathModule == nil then return end
|
||||
local state = states[task]
|
||||
if state == nil then
|
||||
state = {}
|
||||
states[task] = state
|
||||
end
|
||||
local reached = vehicle.ad.drivePathModule:isTargetReached() and not vehicle.ad.trailerModule:isActiveAtTrigger()
|
||||
local level = adEnv.AutoDrive.getAllFillLevels(task.trailers) or 0
|
||||
if ADLoadDiag.tick(state, dt, reached, level) then report(adEnv, task) end
|
||||
end
|
||||
|
||||
local isInstalled = false
|
||||
|
||||
function ADLoadDiag.install(adEnv)
|
||||
local task = adEnv ~= nil and adEnv.LoadAtDestinationTask or nil
|
||||
if isInstalled or task == nil or task.update == nil or adEnv.ADTriggerManager == nil then return end
|
||||
isInstalled = true
|
||||
local original = task.update
|
||||
task.update = function(self, dt)
|
||||
local result = original(self, dt)
|
||||
local ok, err = pcall(ADLoadDiag.after, adEnv, self, dt)
|
||||
if not ok and not self.spuDiagFailed then
|
||||
self.spuDiagFailed = true
|
||||
Logging.warning(ADLoadDiag.LOG_PREFIX .. "diagnose fejlede: %s", tostring(err))
|
||||
end
|
||||
return result
|
||||
end
|
||||
end
|
||||
@@ -1152,6 +1152,9 @@ local function installHook(adEnv)
|
||||
if ADHitchCreep ~= nil and ADHitchCreep.install ~= nil then
|
||||
ADHitchCreep.install(adEnv)
|
||||
end
|
||||
if ADLoadDiag ~= nil and ADLoadDiag.install ~= nil then
|
||||
ADLoadDiag.install(adEnv)
|
||||
end
|
||||
|
||||
Logging.info(ADSmartPickup.LOG_PREFIX .. "aktiv (mindst fyldte silo med varen; flere valgte varer = behovsstyret forsyning; Wait-punkter for rest-læs; udkørsel til silo/salg)")
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<modDesc descVersion="107">
|
||||
<author>masterdraco</author>
|
||||
<version>1.62.4.0</version>
|
||||
<version>1.62.5.0</version>
|
||||
<title>
|
||||
<en>AD Smart Pickup</en>
|
||||
</title>
|
||||
@@ -32,6 +32,7 @@
|
||||
<sourceFile filename="adBuildings.lua"/>
|
||||
<sourceFile filename="adOutbound.lua"/>
|
||||
<sourceFile filename="adTipSide.lua"/>
|
||||
<sourceFile filename="adLoadDiag.lua"/>
|
||||
<sourceFile filename="adUnloadWait.lua"/>
|
||||
<sourceFile filename="adFieldModel.lua"/>
|
||||
<sourceFile filename="adFieldFleet.lua"/>
|
||||
|
||||
Reference in New Issue
Block a user