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:
+175
-41
@@ -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,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
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user