refactor: Wait-puljen udskilt i adWaitPool (reservationer, rutetjek, redirect) til deling med udkørsel
This commit is contained in:
@@ -43,7 +43,8 @@ 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
|
-- 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).
|
-- foretrækkes. Returnerer marker — eller nil + en forklaring (til loggen).
|
||||||
function ADLoadSwap.findDumpMarker(adEnv, vehicle, fillType, rest, homeWayPointId, isReachable)
|
-- excludedPlaceables (valgfri): {[placeable] = true} der aldrig må vælges (fx udkørslens kilder).
|
||||||
|
function ADLoadSwap.findDumpMarker(adEnv, vehicle, fillType, rest, homeWayPointId, isReachable, excludedPlaceables)
|
||||||
if vehicle.rootNode == nil then
|
if vehicle.rootNode == nil then
|
||||||
return nil, "køretøjet har ingen position"
|
return nil, "køretøjet har ingen position"
|
||||||
end
|
end
|
||||||
@@ -54,7 +55,8 @@ function ADLoadSwap.findDumpMarker(adEnv, vehicle, fillType, rest, homeWayPointI
|
|||||||
local silos, withSpace = 0, 0
|
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) then
|
local isExcluded = excludedPlaceables ~= nil and excludedPlaceables[station ~= nil and station.owningPlaceable or false] == true
|
||||||
|
if station ~= nil and isSilo(station, homeStation) and not isExcluded then
|
||||||
silos = silos + 1
|
silos = silos + 1
|
||||||
if acceptsRest(station, fillType, rest, farmId) then
|
if acceptsRest(station, fillType, rest, farmId) then
|
||||||
withSpace = withSpace + 1
|
withSpace = withSpace + 1
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ ADUnloadWait.LOG_PREFIX = "ADSmartPickup: "
|
|||||||
|
|
||||||
-- køretøj -> {task, homeDestinationID, waitMarker, fillType, rest}
|
-- køretøj -> {task, homeDestinationID, waitMarker, fillType, rest}
|
||||||
local waits = setmetatable({}, {__mode = "k"})
|
local waits = setmetatable({}, {__mode = "k"})
|
||||||
-- markør-id -> køretøj der har reserveret Wait-punktet
|
|
||||||
local claims = setmetatable({}, {__mode = "v"})
|
|
||||||
local warnedNoWaitPoint = setmetatable({}, {__mode = "k"})
|
local warnedNoWaitPoint = setmetatable({}, {__mode = "k"})
|
||||||
local isInstalled = false
|
local isInstalled = false
|
||||||
|
|
||||||
@@ -39,72 +37,23 @@ local function getRestLoad(adEnv, vehicle)
|
|||||||
return bestFillType, bestLevel
|
return bestFillType, bestLevel
|
||||||
end
|
end
|
||||||
|
|
||||||
-- poolGroup: run'ets Wait-mappe; tom/nil = alle Wait-mapper.
|
|
||||||
local function getWaitCandidates(adEnv, poolGroup)
|
|
||||||
local candidates = {}
|
|
||||||
for _, marker in pairs(adEnv.ADGraphManager:getMapMarkers()) do
|
|
||||||
local isInPool = poolGroup == nil or poolGroup == "" or marker.group == poolGroup
|
|
||||||
if isInPool and ADSupplyPlanner.isWaitMarker(marker) then
|
|
||||||
local wayPoint = adEnv.ADGraphManager:getWayPointById(marker.id)
|
|
||||||
if wayPoint ~= nil then
|
|
||||||
table.insert(candidates, {marker = marker, x = wayPoint.x, z = wayPoint.z})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return candidates
|
|
||||||
end
|
|
||||||
|
|
||||||
local function getWaitPoolGroup(vehicle)
|
local function getWaitPoolGroup(vehicle)
|
||||||
local run = ADRunsController ~= nil and ADRunsController.getRunForVehicle(vehicle) or nil
|
local run = ADRunsController ~= nil and ADRunsController.getRunForVehicle(vehicle) or nil
|
||||||
return run ~= nil and run.waitPoolGroup or nil
|
return run ~= nil and run.waitPoolGroup or nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local function getVehiclePosition(vehicle)
|
-- Rutetjek, reservationer og omdirigering deles med udkørsels-modulet (adWaitPool).
|
||||||
if vehicle.rootNode == nil then
|
-- Kun "til punktet" ved silo-aflæsning: næste tur er AD's egen rute fra siloen.
|
||||||
return nil
|
|
||||||
end
|
|
||||||
local x, _, z = getWorldTranslation(vehicle.rootNode)
|
|
||||||
return x, z
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Ender ruten i målet? (AutoDrive returnerer tom/afkortet liste når der ingen vej er.)
|
|
||||||
local function pathReaches(path, wayPointId)
|
|
||||||
return path ~= nil and #path > 0 and path[#path].id == wayPointId
|
|
||||||
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 function hasRouteTo(adEnv, vehicle, wayPointId)
|
||||||
local graph = adEnv.ADGraphManager
|
return ADWaitPool.hasRouteTo(adEnv, vehicle, wayPointId)
|
||||||
if graph.getPathTo == nil then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return pathReaches(graph:getPathTo(vehicle, wayPointId), wayPointId)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function hasRouteBothWays(adEnv, vehicle, waitWayPointId, homeWayPointId)
|
local function hasRouteBothWays(adEnv, vehicle, waitWayPointId, homeWayPointId)
|
||||||
local graph = adEnv.ADGraphManager
|
return ADWaitPool.hasRouteBothWays(adEnv, vehicle, waitWayPointId, homeWayPointId)
|
||||||
if graph.getPathTo == nil or graph.pathFromTo == nil then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return pathReaches(graph:getPathTo(vehicle, waitWayPointId), waitWayPointId)
|
|
||||||
and pathReaches(graph:pathFromTo(waitWayPointId, homeWayPointId), homeWayPointId)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Står AD midt i en (blokeret) aflæsning, stoppes den pænt først — ellers kører traktoren
|
|
||||||
-- væk med tippet vogn.
|
|
||||||
local function redirect(task, destinationID)
|
local function redirect(task, destinationID)
|
||||||
local trailerModule = task.vehicle.ad.trailerModule
|
ADWaitPool.redirect(task, destinationID)
|
||||||
if trailerModule ~= nil and trailerModule.isActiveAtTrigger ~= nil and trailerModule:isActiveAtTrigger() then
|
|
||||||
if trailerModule.stopUnloading ~= nil then trailerModule:stopUnloading() end
|
|
||||||
if trailerModule.stopLoading ~= nil then trailerModule:stopLoading() end
|
|
||||||
end
|
|
||||||
task.destinationID = destinationID
|
|
||||||
task.state = ADUnloadWait.STATE_DRIVING
|
|
||||||
task.vehicle.ad.drivePathModule:setPathTo(destinationID)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- køretøj -> AD's oprindelige 2. markør (waypoint-id) mens der læsses af i en silo
|
-- køretøj -> AD's oprindelige 2. markør (waypoint-id) mens der læsses af i en silo
|
||||||
@@ -137,9 +86,8 @@ local function restoreTarget(vehicle)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function release(vehicle)
|
local function release(vehicle)
|
||||||
local wait = waits[vehicle]
|
if waits[vehicle] ~= nil then
|
||||||
if wait ~= nil and claims[wait.waitMarker.id] == vehicle then
|
ADWaitPool.releaseVehicle(vehicle)
|
||||||
claims[wait.waitMarker.id] = nil
|
|
||||||
end
|
end
|
||||||
waits[vehicle] = nil
|
waits[vehicle] = nil
|
||||||
if ADLoadSwap ~= nil then
|
if ADLoadSwap ~= nil then
|
||||||
@@ -199,12 +147,11 @@ local function startWaiting(adEnv, task)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local x, z = getVehiclePosition(vehicle)
|
|
||||||
local isReachable = function(candidate)
|
local isReachable = function(candidate)
|
||||||
return hasRouteBothWays(adEnv, vehicle, candidate.marker.id, task.destinationID)
|
return hasRouteBothWays(adEnv, vehicle, candidate.marker.id, task.destinationID)
|
||||||
end
|
end
|
||||||
local pool = getWaitPoolGroup(vehicle)
|
local pool = getWaitPoolGroup(vehicle)
|
||||||
local candidate = x ~= nil and ADSupplyPlanner.pickNearestFreeWaitPoint(getWaitCandidates(adEnv, pool), claims, x, z, vehicle, isReachable) or nil
|
local candidate = ADWaitPool.pickFree(adEnv, vehicle, pool, isReachable)
|
||||||
if candidate == nil then
|
if candidate == nil then
|
||||||
if not warnedNoWaitPoint[vehicle] then
|
if not warnedNoWaitPoint[vehicle] then
|
||||||
warnedNoWaitPoint[vehicle] = true
|
warnedNoWaitPoint[vehicle] = true
|
||||||
@@ -214,7 +161,7 @@ local function startWaiting(adEnv, task)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
warnedNoWaitPoint[vehicle] = nil
|
warnedNoWaitPoint[vehicle] = nil
|
||||||
claims[candidate.marker.id] = vehicle
|
ADWaitPool.claim(candidate.marker.id, vehicle)
|
||||||
waits[vehicle] = {task = task, homeDestinationID = task.destinationID, waitMarker = candidate.marker, fillType = fillType, rest = rest}
|
waits[vehicle] = {task = task, homeDestinationID = task.destinationID, waitMarker = candidate.marker, fillType = fillType, rest = rest}
|
||||||
-- AD tipper (og holder vognen stille) så længe den står nær sit EGET mål — også i små
|
-- AD tipper (og holder vognen stille) så længe den står nær sit EGET mål — også i små
|
||||||
-- portioner, når målet forbruger løbende. Derfor peger AD's mål på Wait-punktet imens.
|
-- portioner, når målet forbruger løbende. Derfor peger AD's mål på Wait-punktet imens.
|
||||||
@@ -366,20 +313,9 @@ function ADUnloadWait.getWaitFor(vehicle)
|
|||||||
return {markerName = wait.waitMarker ~= nil and wait.waitMarker.name or nil, fillType = wait.fillType, rest = wait.rest}
|
return {markerName = wait.waitMarker ~= nil and wait.waitMarker.name or nil, fillType = wait.fillType, rest = wait.rest}
|
||||||
end
|
end
|
||||||
|
|
||||||
function ADUnloadWait.getClaims()
|
-- Alle reservationer i puljen (også udkørsels-traktorer der holder).
|
||||||
local result = {}
|
function ADUnloadWait.getClaims(adEnv)
|
||||||
for _, wait in pairs(waits) do
|
return ADWaitPool.getClaims(adEnv)
|
||||||
if wait.waitMarker ~= nil and claims[wait.waitMarker.id] ~= nil then
|
|
||||||
table.insert(result, {marker = wait.waitMarker, vehicle = claims[wait.waitMarker.id]})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
table.sort(result, function(a, b)
|
|
||||||
if a.marker.group ~= b.marker.group then
|
|
||||||
return tostring(a.marker.group) < tostring(b.marker.group)
|
|
||||||
end
|
|
||||||
return a.marker.id < b.marker.id
|
|
||||||
end)
|
|
||||||
return result
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function ADUnloadWait.install(adEnv)
|
function ADUnloadWait.install(adEnv)
|
||||||
@@ -389,6 +325,7 @@ function ADUnloadWait.install(adEnv)
|
|||||||
end
|
end
|
||||||
isInstalled = true
|
isInstalled = true
|
||||||
ADUnloadWait.STATE_DRIVING = task.STATE_DRIVING or 2
|
ADUnloadWait.STATE_DRIVING = task.STATE_DRIVING or 2
|
||||||
|
ADWaitPool.STATE_DRIVING = ADUnloadWait.STATE_DRIVING
|
||||||
|
|
||||||
local originalUpdate, originalFinished, originalGetSetting = task.update, task.finished, autoDrive.getSetting
|
local originalUpdate, originalFinished, originalGetSetting = task.update, task.finished, autoDrive.getSetting
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
-- AD Wait Pool
|
||||||
|
-- Fælles pulje af Wait-punkter (markører i mapper med ordet "Wait" i navnet) med
|
||||||
|
-- reservationer, nærmeste-ledige-opslag, rutetjek og omdirigering af en AutoDrive-opgave.
|
||||||
|
-- Bruges af adUnloadWait (rest-læs ved fuldt mål) og adOutbound (hold uden tur).
|
||||||
|
|
||||||
|
ADWaitPool = {}
|
||||||
|
|
||||||
|
ADWaitPool.LOG_PREFIX = "ADSmartPickup: "
|
||||||
|
-- sættes af den der installerer opgave-hooks (task.STATE_DRIVING); 2 er AD's værdi
|
||||||
|
ADWaitPool.STATE_DRIVING = 2
|
||||||
|
|
||||||
|
-- markør-id -> køretøj der har reserveret Wait-punktet
|
||||||
|
ADWaitPool.claims = setmetatable({}, {__mode = "v"})
|
||||||
|
|
||||||
|
-- poolGroup: run'ets Wait-mappe; tom/nil = alle Wait-mapper.
|
||||||
|
function ADWaitPool.getCandidates(adEnv, poolGroup)
|
||||||
|
local candidates = {}
|
||||||
|
for _, marker in pairs(adEnv.ADGraphManager:getMapMarkers()) do
|
||||||
|
local isInPool = poolGroup == nil or poolGroup == "" or marker.group == poolGroup
|
||||||
|
if isInPool and ADSupplyPlanner.isWaitMarker(marker) then
|
||||||
|
local wayPoint = adEnv.ADGraphManager:getWayPointById(marker.id)
|
||||||
|
if wayPoint ~= nil then
|
||||||
|
table.insert(candidates, {marker = marker, x = wayPoint.x, z = wayPoint.z})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return candidates
|
||||||
|
end
|
||||||
|
|
||||||
|
function ADWaitPool.claim(markerId, vehicle)
|
||||||
|
ADWaitPool.claims[markerId] = vehicle
|
||||||
|
end
|
||||||
|
|
||||||
|
function ADWaitPool.getOwner(markerId)
|
||||||
|
return ADWaitPool.claims[markerId]
|
||||||
|
end
|
||||||
|
|
||||||
|
function ADWaitPool.releaseVehicle(vehicle)
|
||||||
|
for markerId, owner in pairs(ADWaitPool.claims) do
|
||||||
|
if owner == vehicle then
|
||||||
|
ADWaitPool.claims[markerId] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function getVehiclePosition(vehicle)
|
||||||
|
if vehicle.rootNode == nil then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local x, _, z = getWorldTranslation(vehicle.rootNode)
|
||||||
|
return x, z
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Nærmeste ledige (eller eget reserverede) Wait-punkt fra vognens position; isReachable(candidate)
|
||||||
|
-- valgfri. nil uden position eller uden brugbart punkt. Reserverer IKKE selv.
|
||||||
|
function ADWaitPool.pickFree(adEnv, vehicle, poolGroup, isReachable)
|
||||||
|
local x, z = getVehiclePosition(vehicle)
|
||||||
|
if x == nil then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
return ADSupplyPlanner.pickNearestFreeWaitPoint(ADWaitPool.getCandidates(adEnv, poolGroup), ADWaitPool.claims, x, z, vehicle, isReachable)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Ender ruten i målet? (AutoDrive returnerer tom/afkortet liste når der ingen vej er.)
|
||||||
|
local function pathReaches(path, wayPointId)
|
||||||
|
return path ~= nil and #path > 0 and path[#path].id == wayPointId
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Sendes AutoDrive mod et punkt uden rute, viser den "cannot reach" og slukker sig selv.
|
||||||
|
-- getPathTo/pathFromTo er rene opslag uden bivirkninger.
|
||||||
|
function ADWaitPool.hasRouteTo(adEnv, vehicle, wayPointId)
|
||||||
|
local graph = adEnv.ADGraphManager
|
||||||
|
if graph.getPathTo == nil then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return pathReaches(graph:getPathTo(vehicle, wayPointId), wayPointId)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ADWaitPool.hasRouteBothWays(adEnv, vehicle, toWayPointId, homeWayPointId)
|
||||||
|
local graph = adEnv.ADGraphManager
|
||||||
|
if graph.getPathTo == nil or graph.pathFromTo == nil then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return pathReaches(graph:getPathTo(vehicle, toWayPointId), toWayPointId)
|
||||||
|
and pathReaches(graph:pathFromTo(toWayPointId, homeWayPointId), homeWayPointId)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Står AD midt i en (blokeret) af-/pålæsning, stoppes den pænt først — ellers kører
|
||||||
|
-- traktoren væk med tippet vogn. Kun opgavens destination ændres.
|
||||||
|
function ADWaitPool.redirect(task, destinationID)
|
||||||
|
local trailerModule = task.vehicle.ad.trailerModule
|
||||||
|
if trailerModule ~= nil and trailerModule.isActiveAtTrigger ~= nil and trailerModule:isActiveAtTrigger() then
|
||||||
|
if trailerModule.stopUnloading ~= nil then trailerModule:stopUnloading() end
|
||||||
|
if trailerModule.stopLoading ~= nil then trailerModule:stopLoading() end
|
||||||
|
end
|
||||||
|
task.destinationID = destinationID
|
||||||
|
task.state = ADWaitPool.STATE_DRIVING
|
||||||
|
task.vehicle.ad.drivePathModule:setPathTo(destinationID)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Hvem holder hvor (GUI'ets Wait-puljer-visning). Sorteret på mappe, dernæst markør-id.
|
||||||
|
function ADWaitPool.getClaims(adEnv)
|
||||||
|
local result = {}
|
||||||
|
local graph = adEnv ~= nil and adEnv.ADGraphManager or (FS25_AutoDrive ~= nil and FS25_AutoDrive.ADGraphManager or nil)
|
||||||
|
for markerId, vehicle in pairs(ADWaitPool.claims) do
|
||||||
|
local marker = graph ~= nil and graph.getMapMarkerByWayPointId ~= nil and graph:getMapMarkerByWayPointId(markerId) or nil
|
||||||
|
if marker ~= nil then
|
||||||
|
table.insert(result, {marker = marker, vehicle = vehicle})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
table.sort(result, function(a, b)
|
||||||
|
if a.marker.group ~= b.marker.group then
|
||||||
|
return tostring(a.marker.group) < tostring(b.marker.group)
|
||||||
|
end
|
||||||
|
return a.marker.id < b.marker.id
|
||||||
|
end)
|
||||||
|
return result
|
||||||
|
end
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
<sourceFile filename="adRunsStorage.lua"/>
|
<sourceFile filename="adRunsStorage.lua"/>
|
||||||
<sourceFile filename="adRunsController.lua"/>
|
<sourceFile filename="adRunsController.lua"/>
|
||||||
<sourceFile filename="adLoadSwap.lua"/>
|
<sourceFile filename="adLoadSwap.lua"/>
|
||||||
|
<sourceFile filename="adWaitPool.lua"/>
|
||||||
<sourceFile filename="adUnloadWait.lua"/>
|
<sourceFile filename="adUnloadWait.lua"/>
|
||||||
<sourceFile filename="adSmartPickup.lua"/>
|
<sourceFile filename="adSmartPickup.lua"/>
|
||||||
</extraSourceFiles>
|
</extraSourceFiles>
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ dofile("FS25_ADSmartPickup/adSupplyPlanner.lua")
|
|||||||
dofile("FS25_ADSmartPickup/adRuns.lua")
|
dofile("FS25_ADSmartPickup/adRuns.lua")
|
||||||
dofile("FS25_ADSmartPickup/adRunsController.lua")
|
dofile("FS25_ADSmartPickup/adRunsController.lua")
|
||||||
dofile("FS25_ADSmartPickup/adLoadSwap.lua")
|
dofile("FS25_ADSmartPickup/adLoadSwap.lua")
|
||||||
|
dofile("FS25_ADSmartPickup/adWaitPool.lua")
|
||||||
dofile("FS25_ADSmartPickup/adUnloadWait.lua")
|
dofile("FS25_ADSmartPickup/adUnloadWait.lua")
|
||||||
dofile("FS25_ADSmartPickup/adSmartPickup.lua")
|
dofile("FS25_ADSmartPickup/adSmartPickup.lua")
|
||||||
listener:update(16) -- installerer hook'en
|
listener:update(16) -- installerer hook'en
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
-- Kør: luajit tests/test_adWaitPool.lua (fra repo-roden)
|
||||||
|
-- Wait-puljen: kandidater pr. mappe, reservationer, nærmeste ledige, rutetjek, redirect.
|
||||||
|
|
||||||
|
dofile("FS25_ADSmartPickup/adSupplyPlanner.lua")
|
||||||
|
dofile("FS25_ADSmartPickup/adWaitPool.lua")
|
||||||
|
|
||||||
|
local failures = 0
|
||||||
|
local function check(name, actual, expected)
|
||||||
|
if actual == expected then
|
||||||
|
print("OK " .. name)
|
||||||
|
else
|
||||||
|
failures = failures + 1
|
||||||
|
print(string.format("FAIL %s: forventede %s, fik %s", name, tostring(expected), tostring(actual)))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local markers, wayPoints = {}, {}
|
||||||
|
local function addMarker(id, name, group, x, z)
|
||||||
|
wayPoints[id] = {id = id, x = x, z = z, incoming = {}}
|
||||||
|
local marker = {id = id, markerIndex = #markers + 1, name = name, group = group}
|
||||||
|
table.insert(markers, marker)
|
||||||
|
return marker
|
||||||
|
end
|
||||||
|
local unreachable = {}
|
||||||
|
local adEnv = {
|
||||||
|
ADGraphManager = {
|
||||||
|
getMapMarkers = function() return markers end,
|
||||||
|
getMapMarkerByWayPointId = function(_, id) for _, m in ipairs(markers) do if m.id == id then return m end end end,
|
||||||
|
getWayPointById = function(_, id) return wayPoints[id] end,
|
||||||
|
getPathTo = function(_, vehicle, id) if unreachable[id] then return {} end return {{id = id}} end,
|
||||||
|
pathFromTo = function(_, from, to) if unreachable[to] then return {} end return {{id = to}} end,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
getWorldTranslation = function(node) return node.x, 0, node.z end
|
||||||
|
|
||||||
|
addMarker(10, "cow wait 1", "cow wait", 0, 0)
|
||||||
|
addMarker(11, "cow wait 2", "cow wait", 50, 0)
|
||||||
|
addMarker(20, "Wait 3", "General Wait", 10, 0)
|
||||||
|
addMarker(30, "silo 1", "silo", 5, 0)
|
||||||
|
|
||||||
|
-- W1: kandidater
|
||||||
|
check("W1 kun mappen", #ADWaitPool.getCandidates(adEnv, "cow wait"), 2)
|
||||||
|
check("W1 tom pulje = alle Wait-mapper", #ADWaitPool.getCandidates(adEnv, ""), 3)
|
||||||
|
check("W1 nil = alle", #ADWaitPool.getCandidates(adEnv, nil), 3)
|
||||||
|
|
||||||
|
-- W2: nærmeste ledige fra vognens position; reserverede springes over; egen reservation OK
|
||||||
|
local v1, v2 = {name = "v1", rootNode = {x = 45, z = 0}}, {name = "v2", rootNode = {x = 45, z = 0}}
|
||||||
|
check("W2 nærmeste", ADWaitPool.pickFree(adEnv, v1, "cow wait").marker.id, 11)
|
||||||
|
ADWaitPool.claim(11, v1)
|
||||||
|
check("W2 reserveret springes over", ADWaitPool.pickFree(adEnv, v2, "cow wait").marker.id, 10)
|
||||||
|
check("W2 egen reservation genbruges", ADWaitPool.pickFree(adEnv, v1, "cow wait").marker.id, 11)
|
||||||
|
|
||||||
|
-- W3: claim / owner / release
|
||||||
|
check("W3 ejer", ADWaitPool.getOwner(11), v1)
|
||||||
|
ADWaitPool.releaseVehicle(v1)
|
||||||
|
check("W3 frigivet", ADWaitPool.getOwner(11), nil)
|
||||||
|
check("W3 nu ledig for v2", ADWaitPool.pickFree(adEnv, v2, "cow wait").marker.id, 11)
|
||||||
|
|
||||||
|
-- W4: nåelighed
|
||||||
|
unreachable[11] = true
|
||||||
|
check("W4 uopnåelig nærmeste -> næste", ADWaitPool.pickFree(adEnv, v2, "cow wait", function(c) return ADWaitPool.hasRouteTo(adEnv, v2, c.marker.id) end).marker.id, 10)
|
||||||
|
check("W4 hasRouteTo false", ADWaitPool.hasRouteTo(adEnv, v2, 11), false)
|
||||||
|
check("W4 hasRouteBothWays true", ADWaitPool.hasRouteBothWays(adEnv, v2, 10, 30), true)
|
||||||
|
check("W4 hasRouteBothWays hjem uopnåelig", ADWaitPool.hasRouteBothWays(adEnv, v2, 10, 11), false)
|
||||||
|
unreachable[11] = nil
|
||||||
|
check("W4 intet punkt -> nil", ADWaitPool.pickFree(adEnv, v2, "cow wait", function() return false end), nil)
|
||||||
|
|
||||||
|
-- W5: getClaims sorteret på mappe, dernæst id
|
||||||
|
ADWaitPool.claim(20, v2)
|
||||||
|
ADWaitPool.claim(10, v1)
|
||||||
|
local claims = ADWaitPool.getClaims(adEnv)
|
||||||
|
check("W5 to reservationer", #claims, 2)
|
||||||
|
check("W5 første = General Wait", claims[1].marker.group, "General Wait")
|
||||||
|
check("W5 anden = cow wait 1", claims[2].marker.id, 10)
|
||||||
|
ADWaitPool.releaseVehicle(v1)
|
||||||
|
ADWaitPool.releaseVehicle(v2)
|
||||||
|
check("W5 alt frigivet", #ADWaitPool.getClaims(adEnv), 0)
|
||||||
|
|
||||||
|
-- W6: redirect stopper trigger-aktivitet og sætter sti
|
||||||
|
local stopped = {}
|
||||||
|
local task = {
|
||||||
|
destinationID = 99, state = 1,
|
||||||
|
vehicle = {ad = {
|
||||||
|
trailerModule = {isActiveAtTrigger = function() return true end, stopUnloading = function() stopped.unload = true end, stopLoading = function() stopped.load = true end},
|
||||||
|
drivePathModule = {setPathTo = function(_, id) stopped.pathTo = id end},
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
ADWaitPool.STATE_DRIVING = 2
|
||||||
|
ADWaitPool.redirect(task, 10)
|
||||||
|
check("W6 destination", task.destinationID, 10)
|
||||||
|
check("W6 state driving", task.state, 2)
|
||||||
|
check("W6 setPathTo", stopped.pathTo, 10)
|
||||||
|
check("W6 stopUnloading", stopped.unload, true)
|
||||||
|
|
||||||
|
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
|
||||||
|
os.exit(failures == 0 and 0 or 1)
|
||||||
Reference in New Issue
Block a user