feat(kobling): Afkobl-markører kobler redskaber bag traktoren af (frontvægt bliver); 'hent vogn og kør til' som ADHitch.trip + konsol spuTrip/spuDetach (v1.47.0.0)

This commit is contained in:
2026-09-28 17:14:20 +02:00
parent fde3fd4399
commit be043ac220
3 changed files with 210 additions and 54 deletions
+175 -41
View File
@@ -1,63 +1,105 @@
-- AD Hitch -- AD Hitch
-- Kobler redskaber på med AutoDrive. En markør der hedder "Connect <navn>" (eller "Kobl <navn>") ligger lige -- Kobler redskaber på og af med AutoDrive.
-- under vognens trækøje, med et bakkespor ned til den. Når en traktor har kørt AD "Kør til" til sådan en markør -- "Connect <navn>" (eller "Kobl <navn>"): markøren ligger lige under vognens trækøje med et bakkespor ned til
-- og står stille, kobles det redskab på, som spillet selv finder inden for koblingsafstand (samme kald som -- den. Når en traktor har kørt AD "Kør til" dertil og står stille, kobles det redskab på, som spillet selv finder
-- Courseplay bruger til skærebord: updateVehiclesInAttachRange + attachImplementFromInfo). -- inden for koblingsafstand (samme kald som Courseplay bruger til skærebord: updateVehiclesInAttachRange +
-- ADHitch.fetch() er indgangen for flows/markarbejde: kør til markøren, kobl på, meld tilbage. -- attachImplementFromInfo).
-- "Afkobl <navn>" (eller "Kobl af", "Detach", "Disconnect"): ved ankomst kobles redskaberne BAG traktoren af;
-- frontvægt og frontlæsser bliver siddende.
-- ADHitch.fetch()/ADHitch.drop() er indgangen for flows/markarbejde: kør til markøren, kobl på/af, meld tilbage.
ADHitch = {} ADHitch = {}
ADHitch.LOG_PREFIX = "ADSmartPickup: kobling: " ADHitch.LOG_PREFIX = "ADSmartPickup: kobling: "
ADHitch.PREFIXES = {"connect", "kobl"} -- afkobling tjekkes først, så "Kobl af X" ikke læses som "Kobl <af X>"
ADHitch.MARKER_PREFIXES = {
{prefix = "afkobl", action = "detach"},
{prefix = "kobl af", action = "detach"},
{prefix = "detach", action = "detach"},
{prefix = "disconnect", action = "detach"},
{prefix = "connect", action = "attach"},
{prefix = "kobl", action = "attach"},
}
ADHitch.TIMEOUT_REASON = {attach = "noAttachable", detach = "nothingToDetach"}
ADHitch.ARRIVE_DISTANCE = 5 -- m fra markøren, AD standser traktoren tæt på waypointet ADHitch.ARRIVE_DISTANCE = 5 -- m fra markøren, AD standser traktoren tæt på waypointet
ADHitch.STILL_SPEED = 1 -- km/t ADHitch.STILL_SPEED = 1 -- km/t
ADHitch.START_GRACE_MS = 3000 -- så længe må AD være om at komme i gang efter fetch ADHitch.START_GRACE_MS = 3000 -- så længe må AD være om at komme i gang efter fetch/drop
ADHitch.ATTACH_TIMEOUT_MS = 8000 -- så længe forsøges koblingen efter ankomst ADHitch.ACT_TIMEOUT_MS = 8000 -- så længe forsøges kobling/afkobling efter ankomst
ADHitch.TICK_MS = 250 ADHitch.TICK_MS = 250
-- ---- ren logik ---- -- ---- ren logik ----
-- "Connect Bredal" -> "Bredal"; "Connect" -> ""; andre navne -> nil -- "Connect Bredal" -> "attach", "Bredal"; "Afkobl" -> "detach", ""; andre navne -> nil
function ADHitch.connectTarget(name) function ADHitch.parseMarker(name)
if type(name) ~= "string" then return nil end if type(name) ~= "string" then return nil end
local trimmed = name:match("^%s*(.-)%s*$") local trimmed = name:match("^%s*(.-)%s*$")
local lower = trimmed:lower() local lower = trimmed:lower()
for _, prefix in ipairs(ADHitch.PREFIXES) do for _, entry in ipairs(ADHitch.MARKER_PREFIXES) do
if lower == prefix then return "" end local prefix = entry.prefix
if lower == prefix then return entry.action, "" end
if lower:sub(1, #prefix + 1) == prefix .. " " then if lower:sub(1, #prefix + 1) == prefix .. " " then
return (trimmed:sub(#prefix + 2):match("^%s*(.-)$")) return entry.action, (trimmed:sub(#prefix + 2):match("^%s*(.-)$"))
end end
end end
return nil return nil
end end
-- implements = {{z = position i traktorens rum, ...}} -> kun dem bag traktoren
function ADHitch.rearImplements(implements)
local rear = {}
for _, implement in ipairs(implements or {}) do
if implement.z ~= nil and implement.z < 0 then table.insert(rear, implement) end
end
return rear
end
-- konsol-argumenter "Connect Bredal > Start" -> "Connect Bredal", "Start" (mål nil uden ">")
function ADHitch.parseTrip(...)
local text = table.concat({...}, " ")
local first, second = text:match("^%s*(.-)%s*>%s*(.-)%s*$")
if first == nil then return (text:match("^%s*(.-)%s*$")), nil end
return first, second
end
-- markers = {{name, id}} -> markøren med navnet (store/små bogstaver ligegyldigt)
function ADHitch.findMarker(markers, name)
if type(name) ~= "string" then return nil end
local wanted = name:lower()
for _, marker in pairs(markers or {}) do
if type(marker.name) == "string" and marker.name:lower() == wanted then return marker end
end
return nil
end
-- state = {adActive, distance, speed} -- state = {adActive, distance, speed}
function ADHitch.hasArrived(state) function ADHitch.hasArrived(state)
return not state.adActive and state.distance <= ADHitch.ARRIVE_DISTANCE and state.speed <= ADHitch.STILL_SPEED return not state.adActive and state.distance <= ADHitch.ARRIVE_DISTANCE and state.speed <= ADHitch.STILL_SPEED
end end
function ADHitch.newJob(markerId, markerName) function ADHitch.newJob(markerId, markerName, action)
return {markerId = markerId, markerName = markerName, state = "driving", elapsed = 0, attachElapsed = 0, return {markerId = markerId, markerName = markerName, action = action, state = "driving", elapsed = 0,
seenActive = false} actElapsed = 0, seenActive = false}
end end
-- Et skridt i jobbet. attached = lykkedes koblingsforsøget i denne tick (kun relevant i "attaching"). -- Et skridt i jobbet. succeeded = lykkedes kobling/afkobling i denne tick (kun relevant i "acting").
-- Tilstande: driving -> attaching -> done | failed (reason: stoppedAway / noAttachable) -- Tilstande: driving -> acting -> done | failed (reason: stoppedAway / noAttachable / nothingToDetach)
function ADHitch.step(job, state, dt, attached) function ADHitch.step(job, state, dt, succeeded)
if job.state == "driving" then if job.state == "driving" then
job.elapsed = job.elapsed + dt job.elapsed = job.elapsed + dt
if state.adActive then if state.adActive then
job.seenActive = true job.seenActive = true
elseif ADHitch.hasArrived(state) then elseif ADHitch.hasArrived(state) then
job.state = "attaching" job.state = "acting"
elseif state.distance > ADHitch.ARRIVE_DISTANCE and (job.seenActive or job.elapsed >= ADHitch.START_GRACE_MS) then elseif state.distance > ADHitch.ARRIVE_DISTANCE and (job.seenActive or job.elapsed >= ADHitch.START_GRACE_MS) then
job.state, job.reason = "failed", "stoppedAway" job.state, job.reason = "failed", "stoppedAway"
end end
elseif job.state == "attaching" then elseif job.state == "acting" then
if attached then if succeeded then
job.state = "done" job.state = "done"
else else
job.attachElapsed = job.attachElapsed + dt job.actElapsed = job.actElapsed + dt
if job.attachElapsed >= ADHitch.ATTACH_TIMEOUT_MS then job.state, job.reason = "failed", "noAttachable" end if job.actElapsed >= ADHitch.ACT_TIMEOUT_MS then
job.state, job.reason = "failed", ADHitch.TIMEOUT_REASON[job.action]
end
end end
end end
return job return job
@@ -69,6 +111,7 @@ local jobs = setmetatable({}, {__mode = "k"}) -- [vehicle] = job (+ onDone)
local tickTimer = 0 local tickTimer = 0
local function vehicleName(vehicle) local function vehicleName(vehicle)
if type(vehicle) ~= "table" then return tostring(vehicle) end
return vehicle.getFullName ~= nil and vehicle:getFullName() or tostring(vehicle.configFileName) return vehicle.getFullName ~= nil and vehicle:getFullName() or tostring(vehicle.configFileName)
end end
@@ -109,10 +152,40 @@ function ADHitch.tryAttach(vehicle)
return true, info.attachable return true, info.attachable
end end
-- Kør til en Connect-markør og kobl på. onDone(vehicle, ok, implementOrReason) kaldes én gang. -- Redskaber koblet direkte på traktoren, med deres placering langs traktoren (z > 0 foran, z < 0 bagved).
function ADHitch.fetch(adEnv, vehicle, markerId, onDone) local function attachedImplements(vehicle)
local list = {}
if vehicle.getAttachedImplements == nil then return list end
for _, implement in ipairs(vehicle:getAttachedImplements()) do
local jointDesc = vehicle.spec_attacherJoints.attacherJoints[implement.jointDescIndex]
local node = jointDesc ~= nil and (jointDesc.jointTransform or jointDesc.rootNode) or nil
if implement.object ~= nil and node ~= nil then
local _, _, z = localToLocal(node, vehicle.rootNode, 0, 0, 0)
table.insert(list, {object = implement.object, z = z, name = vehicleName(implement.object)})
end
end
return list
end
-- Kobler redskaberne bag traktoren af. -> ok, navne eller årsag
function ADHitch.tryDetach(vehicle)
local rear = ADHitch.rearImplements(attachedImplements(vehicle))
if #rear == 0 then return false, "nothingToDetach" end
local names = {}
for _, implement in ipairs(rear) do
local object = implement.object
local allowed, warning = true, nil
if object.isDetachAllowed ~= nil then allowed, warning = object:isDetachAllowed() end
if not allowed then return false, tostring(warning or "detachNotAllowed") end
vehicle:detachImplementByObject(object)
table.insert(names, implement.name)
end
return true, table.concat(names, ", ")
end
local function start(adEnv, vehicle, markerId, action, onDone)
local marker = adEnv.ADGraphManager:getMapMarkerByWayPointId(markerId) local marker = adEnv.ADGraphManager:getMapMarkerByWayPointId(markerId)
local job = ADHitch.newJob(markerId, marker ~= nil and marker.name or tostring(markerId)) local job = ADHitch.newJob(markerId, marker ~= nil and marker.name or tostring(markerId), action)
job.onDone = onDone job.onDone = onDone
jobs[vehicle] = job jobs[vehicle] = job
ADFieldWork.startAd(adEnv, vehicle, adEnv.AutoDrive.MODE_DRIVETO, markerId) ADFieldWork.startAd(adEnv, vehicle, adEnv.AutoDrive.MODE_DRIVETO, markerId)
@@ -120,32 +193,61 @@ function ADHitch.fetch(adEnv, vehicle, markerId, onDone)
return job return job
end end
-- Spilleren sender selv en traktor til en Connect-markør med AD "Kør til": den kobles også på. -- Kør til en Connect-markør og kobl på. onDone(vehicle, ok, redskab eller årsag) kaldes én gang.
function ADHitch.fetch(adEnv, vehicle, markerId, onDone)
return start(adEnv, vehicle, markerId, "attach", onDone)
end
-- Kør til en Afkobl-markør og kobl af. onDone(vehicle, ok, navne eller årsag) kaldes én gang.
function ADHitch.drop(adEnv, vehicle, markerId, onDone)
return start(adEnv, vehicle, markerId, "detach", onDone)
end
-- "Hent vogn og kør til": kør til Connect-markøren, kobl på, kør så med AD til målet.
function ADHitch.trip(adEnv, vehicle, connectId, destinationId, onDone)
return ADHitch.fetch(adEnv, vehicle, connectId, function(tractor, ok, detail)
if not ok then
if onDone ~= nil then onDone(tractor, false, detail) end
return
end
local destination = adEnv.ADGraphManager:getMapMarkerByWayPointId(destinationId)
ADFieldWork.startAd(adEnv, tractor, adEnv.AutoDrive.MODE_DRIVETO, destinationId)
Logging.info(ADHitch.LOG_PREFIX .. "'%s' kører med '%s' til '%s'", vehicleName(tractor), vehicleName(detail),
destination ~= nil and destination.name or tostring(destinationId))
if onDone ~= nil then onDone(tractor, true, detail) end
end)
end
-- Spilleren sender selv en traktor til en Connect-/Afkobl-markør med AD "Kør til": den kobles også.
local function watchManualTrips(adEnv) local function watchManualTrips(adEnv)
for _, vehicle in ipairs(ADRunsController.getFarmVehicles(adEnv)) do for _, vehicle in ipairs(ADRunsController.getFarmVehicles(adEnv)) do
local module = stateModule(vehicle) local module = stateModule(vehicle)
if jobs[vehicle] == nil and vehicle.spec_attacherJoints ~= nil and module ~= nil and module:isActive() if jobs[vehicle] == nil and vehicle.spec_attacherJoints ~= nil and module ~= nil and module:isActive()
and module:getMode() == adEnv.AutoDrive.MODE_DRIVETO then and module:getMode() == adEnv.AutoDrive.MODE_DRIVETO then
local marker = module:getFirstMarker() local marker = module:getFirstMarker()
if marker ~= nil and ADHitch.connectTarget(marker.name) ~= nil then local action = marker ~= nil and ADHitch.parseMarker(marker.name) or nil
jobs[vehicle] = ADHitch.newJob(marker.id, marker.name) if action ~= nil then jobs[vehicle] = ADHitch.newJob(marker.id, marker.name, action) end
end
end end
end end
end end
local DONE_TEXT = {attach = "koblede '%s' på", detach = "koblede '%s' af"}
local FAIL_TEXT = {attach = "kunne ikke koble på", detach = "kunne ikke koble af"}
local function finish(vehicle, job, ok, detail) local function finish(vehicle, job, ok, detail)
jobs[vehicle] = nil jobs[vehicle] = nil
if ok then if ok then
Logging.info(ADHitch.LOG_PREFIX .. "'%s' koblede '%s' på ved '%s'", vehicleName(vehicle), vehicleName(detail), Logging.info(ADHitch.LOG_PREFIX .. "'%s' " .. DONE_TEXT[job.action] .. " ved '%s'", vehicleName(vehicle),
job.markerName) vehicleName(detail), job.markerName)
else else
Logging.warning(ADHitch.LOG_PREFIX .. "'%s' kunne ikke koble på ved '%s': %s", vehicleName(vehicle), Logging.warning(ADHitch.LOG_PREFIX .. "'%s' %s ved '%s': %s", vehicleName(vehicle), FAIL_TEXT[job.action],
job.markerName, tostring(detail)) job.markerName, tostring(detail))
end end
if job.onDone ~= nil then pcall(job.onDone, vehicle, ok, detail) end if job.onDone ~= nil then pcall(job.onDone, vehicle, ok, detail) end
end end
local ACTIONS = {attach = ADHitch.tryAttach, detach = ADHitch.tryDetach}
function ADHitch.tick(adEnv, dt) function ADHitch.tick(adEnv, dt)
if adEnv == nil or adEnv.ADGraphManager == nil then return end if adEnv == nil or adEnv.ADGraphManager == nil then return end
tickTimer = tickTimer + dt tickTimer = tickTimer + dt
@@ -154,12 +256,12 @@ function ADHitch.tick(adEnv, dt)
tickTimer = 0 tickTimer = 0
watchManualTrips(adEnv) watchManualTrips(adEnv)
for vehicle, job in pairs(jobs) do for vehicle, job in pairs(jobs) do
local attached, detail = false, nil local succeeded, detail = false, nil
if job.state == "attaching" then if job.state == "acting" then
attached, detail = ADHitch.tryAttach(vehicle) succeeded, detail = ACTIONS[job.action](vehicle)
if not attached then job.lastReason = detail end if not succeeded then job.lastReason = detail end
end end
ADHitch.step(job, vehicleState(adEnv, vehicle, job.markerId), elapsed, attached) ADHitch.step(job, vehicleState(adEnv, vehicle, job.markerId), elapsed, succeeded)
if job.state == "done" then if job.state == "done" then
finish(vehicle, job, true, detail) finish(vehicle, job, true, detail)
elseif job.state == "failed" then elseif job.state == "failed" then
@@ -168,15 +270,47 @@ function ADHitch.tick(adEnv, dt)
end end
end end
-- Konsol: "spuConnect" kobler det nærmeste redskab på den maskine spilleren sidder i. -- Konsol: "spuConnect" / "spuDetach" på den maskine spilleren sidder i.
local function currentVehicle()
return g_localPlayer ~= nil and g_localPlayer.getCurrentVehicle ~= nil and g_localPlayer:getCurrentVehicle() or nil
end
function ADHitch:consoleConnect() function ADHitch:consoleConnect()
local vehicle = g_localPlayer ~= nil and g_localPlayer.getCurrentVehicle ~= nil and g_localPlayer:getCurrentVehicle() or nil local vehicle = currentVehicle()
if vehicle == nil then return "spuConnect: sæt dig i en traktor først" end if vehicle == nil then return "spuConnect: sæt dig i en traktor først" end
local ok, detail = ADHitch.tryAttach(vehicle) local ok, detail = ADHitch.tryAttach(vehicle)
if ok then return "spuConnect: koblede " .. vehicleName(detail) .. " på" end if ok then return "spuConnect: koblede " .. vehicleName(detail) .. " på" end
return "spuConnect: intet koblet på (" .. tostring(detail) .. ")" return "spuConnect: intet koblet på (" .. tostring(detail) .. ")"
end end
function ADHitch:consoleDetach()
local vehicle = currentVehicle()
if vehicle == nil then return "spuDetach: sæt dig i en traktor først" end
local ok, detail = ADHitch.tryDetach(vehicle)
if ok then return "spuDetach: koblede " .. tostring(detail) .. " af" end
return "spuDetach: intet koblet af (" .. tostring(detail) .. ")"
end
-- "spuTrip Connect Bredal > Start": maskinen spilleren sidder i henter vognen og kører til målet (spilleren
-- kan blive siddende; AD kører også med spilleren i førerhuset).
function ADHitch:consoleTrip(...)
local vehicle = currentVehicle()
if vehicle == nil then return "spuTrip: sæt dig i en traktor først" end
local adEnv = ADFieldSilos ~= nil and ADFieldSilos.adEnv or nil
if adEnv == nil then return "spuTrip: AutoDrive er ikke klar endnu" end
local connectName, destinationName = ADHitch.parseTrip(...)
local markers = adEnv.ADGraphManager:getMapMarkers()
local connect, destination = ADHitch.findMarker(markers, connectName), ADHitch.findMarker(markers, destinationName)
if connect == nil or ADHitch.parseMarker(connect.name) ~= "attach" then
return "spuTrip: ukendt Connect-markør '" .. tostring(connectName) .. "'"
end
if destination == nil then return "spuTrip: ukendt mål '" .. tostring(destinationName) .. "' (brug: spuTrip Connect Bredal > Start)" end
ADHitch.trip(adEnv, vehicle, connect.id, destination.id)
return "spuTrip: " .. vehicleName(vehicle) .. " henter ved '" .. connect.name .. "' og kører til '" .. destination.name .. "'"
end
if addConsoleCommand ~= nil then if addConsoleCommand ~= nil then
addConsoleCommand("spuConnect", "Kobler nærmeste redskab på den maskine du sidder i", "consoleConnect", ADHitch) addConsoleCommand("spuConnect", "Kobler nærmeste redskab på den maskine du sidder i", "consoleConnect", ADHitch)
addConsoleCommand("spuTrip", "Hent vogn og kør: spuTrip Connect Bredal > Start", "consoleTrip", ADHitch)
addConsoleCommand("spuDetach", "Kobler redskaberne bag den maskine du sidder i af", "consoleDetach", ADHitch)
end end
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?> <?xml version="1.0" encoding="utf-8" standalone="no"?>
<modDesc descVersion="107"> <modDesc descVersion="107">
<author>masterdraco</author> <author>masterdraco</author>
<version>1.46.0.0</version> <version>1.47.0.0</version>
<title> <title>
<en>AD Smart Pickup</en> <en>AD Smart Pickup</en>
</title> </title>
+34 -12
View File
@@ -8,39 +8,61 @@ local function check(name, actual, expected)
print(string.format("FAIL %s: forventede %s, fik %s", name, tostring(expected), tostring(actual))) print(string.format("FAIL %s: forventede %s, fik %s", name, tostring(expected), tostring(actual)))
end end
end end
-- markørnavne: "Connect <navn>" (store/små bogstaver ligegyldigt), også dansk "Kobl <navn>" -- markørnavne -> handling + navn (store/små bogstaver ligegyldigt)
check("navn: Connect Bredal", H.connectTarget("Connect Bredal"), "Bredal") local function parsed(name) local a, n = H.parseMarker(name) return tostring(a) .. "|" .. tostring(n) end
check("navn: små bogstaver", H.connectTarget("connect bredal"), "bredal") check("navn: Connect Bredal", parsed("Connect Bredal"), "attach|Bredal")
check("navn: dansk Kobl", H.connectTarget("Kobl Vogn 2"), "Vogn 2") check("navn: små bogstaver", parsed("connect bredal"), "attach|bredal")
check("navn: kun Connect", H.connectTarget("Connect"), "") check("navn: dansk Kobl", parsed("Kobl Vogn 2"), "attach|Vogn 2")
check("navn: Connected er ikke en koblingsmarkør", H.connectTarget("Connected silo"), nil) check("navn: kun Connect", parsed("Connect"), "attach|")
check("navn: almindelig markør", H.connectTarget("Bredal"), nil) check("navn: Connected er ikke en koblingsmarkør", parsed("Connected silo"), "nil|nil")
check("navn: nil", H.connectTarget(nil), nil) check("navn: almindelig markør", parsed("Bredal"), "nil|nil")
check("navn: nil", parsed(nil), "nil|nil")
check("navn: Afkobl Bredal", parsed("Afkobl Bredal"), "detach|Bredal")
check("navn: Kobl af er afkobling, ikke kobling", parsed("Kobl af Bredal"), "detach|Bredal")
check("navn: Detach", parsed("detach"), "detach|")
check("navn: Disconnect", parsed("Disconnect Vogn"), "detach|Vogn")
-- bagerste redskaber: kun led bag traktoren (z < 0 i traktorens rum), ikke frontvægt/frontlæsser
local rear = H.rearImplements({{name = "vægt", z = 3.1}, {name = "Bredal", z = -2.4}, {name = "læsser", z = 1.5}, {name = "plov", z = -1}})
check("bag: kun bagerste", #rear, 2)
check("bag: første", rear[1].name, "Bredal")
-- ankomst: AD er stoppet, traktoren står stille tæt på markøren -- ankomst: AD er stoppet, traktoren står stille tæt på markøren
check("ankomst: stoppet ved markør", H.hasArrived({adActive = false, distance = 1.2, speed = 0.1}), true) check("ankomst: stoppet ved markør", H.hasArrived({adActive = false, distance = 1.2, speed = 0.1}), true)
check("ankomst: AD kører stadig", H.hasArrived({adActive = true, distance = 0.5, speed = 0}), false) check("ankomst: AD kører stadig", H.hasArrived({adActive = true, distance = 0.5, speed = 0}), false)
check("ankomst: for langt væk", H.hasArrived({adActive = false, distance = 9, speed = 0}), false) check("ankomst: for langt væk", H.hasArrived({adActive = false, distance = 9, speed = 0}), false)
check("ankomst: ruller stadig", H.hasArrived({adActive = false, distance = 1, speed = 3}), false) check("ankomst: ruller stadig", H.hasArrived({adActive = false, distance = 1, speed = 3}), false)
-- vagten: efter ankomst forsøges koblingen et stykke tid, derefter opgives den -- vagten: efter ankomst forsøges koblingen et stykke tid, derefter opgives den
local job = H.newJob(25, "Connect Bredal") local job = H.newJob(25, "Connect Bredal", "attach")
check("job: venter på AD", job.state, "driving") check("job: venter på AD", job.state, "driving")
check("job: handling", job.action, "attach")
H.step(job, {adActive = true, distance = 30, speed = 10}, 1000, false) H.step(job, {adActive = true, distance = 30, speed = 10}, 1000, false)
check("job: kører stadig", job.state, "driving") check("job: kører stadig", job.state, "driving")
H.step(job, {adActive = false, distance = 1, speed = 0}, 500, false) H.step(job, {adActive = false, distance = 1, speed = 0}, 500, false)
check("job: ankommet, kobling ikke lykkedes endnu", job.state, "attaching") check("job: ankommet, kobling ikke lykkedes endnu", job.state, "acting")
H.step(job, {adActive = false, distance = 1, speed = 0}, 500, true) H.step(job, {adActive = false, distance = 1, speed = 0}, 500, true)
check("job: koblet på", job.state, "done") check("job: koblet på", job.state, "done")
local failJob = H.newJob(25, "Connect Bredal") local failJob = H.newJob(25, "Connect Bredal", "attach")
H.step(failJob, {adActive = false, distance = 1, speed = 0}, 500, false) H.step(failJob, {adActive = false, distance = 1, speed = 0}, 500, false)
for _ = 1, 20 do H.step(failJob, {adActive = false, distance = 1, speed = 0}, 500, false) end for _ = 1, 20 do H.step(failJob, {adActive = false, distance = 1, speed = 0}, 500, false) end
check("job: opgivet efter vagt-tid", failJob.state, "failed") check("job: opgivet efter vagt-tid", failJob.state, "failed")
check("job: årsag", failJob.reason, "noAttachable") check("job: årsag", failJob.reason, "noAttachable")
local lostJob = H.newJob(25, "Connect Bredal") local dropJob = H.newJob(9, "Afkobl Bredal", "detach")
H.step(dropJob, {adActive = false, distance = 1, speed = 0}, 500, false)
for _ = 1, 20 do H.step(dropJob, {adActive = false, distance = 1, speed = 0}, 500, false) end
check("job: afkobling opgivet", dropJob.reason, "nothingToDetach")
local lostJob = H.newJob(25, "Connect Bredal", "attach")
H.step(lostJob, {adActive = false, distance = 40, speed = 0}, 500, false) H.step(lostJob, {adActive = false, distance = 40, speed = 0}, 500, false)
check("job: AD ikke startet endnu (opstart-frist)", lostJob.state, "driving") check("job: AD ikke startet endnu (opstart-frist)", lostJob.state, "driving")
H.step(lostJob, {adActive = true, distance = 40, speed = 5}, 500, false) H.step(lostJob, {adActive = true, distance = 40, speed = 5}, 500, false)
H.step(lostJob, {adActive = false, distance = 40, speed = 0}, 500, false) H.step(lostJob, {adActive = false, distance = 40, speed = 0}, 500, false)
check("job: AD stoppede langt fra markøren", lostJob.state, "failed") check("job: AD stoppede langt fra markøren", lostJob.state, "failed")
check("job: årsag stoppet undervejs", lostJob.reason, "stoppedAway") check("job: årsag stoppet undervejs", lostJob.reason, "stoppedAway")
-- tur: "Connect Bredal > Start" -> to markørnavne
local a, b = H.parseTrip("Connect", "Bredal", ">", "Start")
check("tur: hent", a, "Connect Bredal")
check("tur: mål", b, "Start")
check("tur: uden mål", select(2, H.parseTrip("Connect", "Bredal")), nil)
local markers = {{name = "Start", id = 1}, {name = "Connect Bredal", id = 9}}
check("markør: navn uden hensyn til store/små", H.findMarker(markers, "connect bredal").id, 9)
check("markør: ukendt", H.findMarker(markers, "Stald"), nil)
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL")) print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
os.exit(failures == 0 and 0 or 1) os.exit(failures == 0 and 0 or 1)