feat(kobling): spuTrip kører en tur i flere trin — Connect kobler på, Afkobl kobler af, almindelige markører holder 10 s undervejs (v1.47.1.0)
This commit is contained in:
@@ -19,12 +19,13 @@ ADHitch.MARKER_PREFIXES = {
|
||||
{prefix = "connect", action = "attach"},
|
||||
{prefix = "kobl", action = "attach"},
|
||||
}
|
||||
ADHitch.TIMEOUT_REASON = {attach = "noAttachable", detach = "nothingToDetach"}
|
||||
ADHitch.TIMEOUT_REASON = {attach = "noAttachable", detach = "nothingToDetach", arrive = "notArrived"}
|
||||
ADHitch.ARRIVE_DISTANCE = 5 -- m fra markøren, AD standser traktoren tæt på waypointet
|
||||
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/drop
|
||||
ADHitch.ACT_TIMEOUT_MS = 8000 -- så længe forsøges kobling/afkobling efter ankomst
|
||||
ADHitch.TICK_MS = 250
|
||||
ADHitch.ROUTE_WAIT_MS = 10000 -- pause ved almindelige markører midt i en tur
|
||||
|
||||
-- ---- ren logik ----
|
||||
|
||||
@@ -52,12 +53,25 @@ function ADHitch.rearImplements(implements)
|
||||
return rear
|
||||
end
|
||||
|
||||
-- konsol-argumenter "Connect Bredal > Start" -> "Connect Bredal", "Start" (mål nil uden ">")
|
||||
-- konsol-argumenter "Connect Bredal > Start > Afkobl Bredal > Start" -> {"Connect Bredal", "Start", ...}
|
||||
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
|
||||
local steps = {}
|
||||
for part in (table.concat({...}, " ") .. ">"):gmatch("([^>]*)>") do
|
||||
local name = part:match("^%s*(.-)%s*$")
|
||||
if name ~= "" then table.insert(steps, name) end
|
||||
end
|
||||
return steps
|
||||
end
|
||||
|
||||
-- markørnavn -> attach / detach / arrive (almindelig markør: bare køre dertil)
|
||||
function ADHitch.stepAction(name)
|
||||
return ADHitch.parseMarker(name) or "arrive"
|
||||
end
|
||||
|
||||
-- pause efter et trin: ved almindelige markører undervejs holdes der, ikke efter sidste trin
|
||||
function ADHitch.waitAfter(action, index, count)
|
||||
if action == "arrive" and index < count then return ADHitch.ROUTE_WAIT_MS end
|
||||
return 0
|
||||
end
|
||||
|
||||
-- markers = {{name, id}} -> markøren med navnet (store/små bogstaver ligegyldigt)
|
||||
@@ -203,19 +217,47 @@ 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
|
||||
-- Tur: markørerne køres i rækkefølge. Connect = kobl på, Afkobl = kobl af, andre = kør dertil (og hold
|
||||
-- ROUTE_WAIT_MS, hvis det ikke er sidste trin). Stopper ved første fejl. onDone(vehicle, ok, årsag) til sidst.
|
||||
local waits = {} -- {vehicle, leftMs, continue}
|
||||
|
||||
function ADHitch.route(adEnv, vehicle, markerIds, onDone)
|
||||
local function runStep(index)
|
||||
if index > #markerIds then
|
||||
Logging.info(ADHitch.LOG_PREFIX .. "'%s' er færdig med turen (%d trin)", vehicleName(vehicle), #markerIds)
|
||||
if onDone ~= nil then pcall(onDone, vehicle, true) 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)
|
||||
local marker = adEnv.ADGraphManager:getMapMarkerByWayPointId(markerIds[index])
|
||||
local action = ADHitch.stepAction(marker ~= nil and marker.name or nil)
|
||||
start(adEnv, vehicle, markerIds[index], action, function(_, ok, detail)
|
||||
if not ok then
|
||||
Logging.warning(ADHitch.LOG_PREFIX .. "'%s' stopper turen ved trin %d", vehicleName(vehicle), index)
|
||||
if onDone ~= nil then pcall(onDone, vehicle, false, detail) end
|
||||
return
|
||||
end
|
||||
local waitMs = ADHitch.waitAfter(action, index, #markerIds)
|
||||
if waitMs > 0 then
|
||||
Logging.info(ADHitch.LOG_PREFIX .. "'%s' holder %d s ved '%s'", vehicleName(vehicle), waitMs / 1000,
|
||||
marker ~= nil and marker.name or "?")
|
||||
table.insert(waits, {vehicle = vehicle, leftMs = waitMs, continue = function() runStep(index + 1) end})
|
||||
else
|
||||
runStep(index + 1)
|
||||
end
|
||||
end)
|
||||
end
|
||||
runStep(1)
|
||||
end
|
||||
|
||||
local function tickWaits(elapsed)
|
||||
for i = #waits, 1, -1 do
|
||||
local wait = waits[i]
|
||||
wait.leftMs = wait.leftMs - elapsed
|
||||
if wait.leftMs <= 0 then
|
||||
table.remove(waits, i)
|
||||
wait.continue()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Spilleren sender selv en traktor til en Connect-/Afkobl-markør med AD "Kør til": den kobles også.
|
||||
@@ -231,8 +273,8 @@ local function watchManualTrips(adEnv)
|
||||
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 DONE_TEXT = {attach = "koblede '%s' på", detach = "koblede '%s' af", arrive = "er fremme%s"}
|
||||
local FAIL_TEXT = {attach = "kunne ikke koble på", detach = "kunne ikke koble af", arrive = "nåede ikke frem"}
|
||||
|
||||
local function finish(vehicle, job, ok, detail)
|
||||
jobs[vehicle] = nil
|
||||
@@ -246,7 +288,7 @@ local function finish(vehicle, job, ok, detail)
|
||||
if job.onDone ~= nil then pcall(job.onDone, vehicle, ok, detail) end
|
||||
end
|
||||
|
||||
local ACTIONS = {attach = ADHitch.tryAttach, detach = ADHitch.tryDetach}
|
||||
local ACTIONS = {attach = ADHitch.tryAttach, detach = ADHitch.tryDetach, arrive = function() return true, "" end}
|
||||
|
||||
function ADHitch.tick(adEnv, dt)
|
||||
if adEnv == nil or adEnv.ADGraphManager == nil then return end
|
||||
@@ -254,8 +296,12 @@ function ADHitch.tick(adEnv, dt)
|
||||
if tickTimer < ADHitch.TICK_MS then return end
|
||||
local elapsed = tickTimer
|
||||
tickTimer = 0
|
||||
tickWaits(elapsed)
|
||||
watchManualTrips(adEnv)
|
||||
for vehicle, job in pairs(jobs) do
|
||||
-- kopi: et færdigt trin starter næste trin (nyt job på samme maskine) midt i løkken
|
||||
local current = {}
|
||||
for vehicle, job in pairs(jobs) do current[vehicle] = job end
|
||||
for vehicle, job in pairs(current) do
|
||||
local succeeded, detail = false, nil
|
||||
if job.state == "acting" then
|
||||
succeeded, detail = ACTIONS[job.action](vehicle)
|
||||
@@ -291,26 +337,27 @@ function ADHitch:consoleDetach()
|
||||
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).
|
||||
-- "spuTrip Connect Bredal > Start > Afkobl Bredal > Start": maskinen spilleren sidder i kører turen
|
||||
-- (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) .. "'"
|
||||
local names = ADHitch.parseTrip(...)
|
||||
if #names == 0 then return "spuTrip: brug fx spuTrip Connect Bredal > Start > Afkobl Bredal > Start" end
|
||||
local markers, ids = adEnv.ADGraphManager:getMapMarkers(), {}
|
||||
for _, name in ipairs(names) do
|
||||
local marker = ADHitch.findMarker(markers, name)
|
||||
if marker == nil then return "spuTrip: ukendt markør '" .. name .. "'" end
|
||||
table.insert(ids, marker.id)
|
||||
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 .. "'"
|
||||
ADHitch.route(adEnv, vehicle, ids)
|
||||
return "spuTrip: " .. vehicleName(vehicle) .. " kører " .. table.concat(names, " > ")
|
||||
end
|
||||
|
||||
if addConsoleCommand ~= nil then
|
||||
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("spuTrip", "Kør en tur: spuTrip Connect Bredal > Start > Afkobl Bredal > Start", "consoleTrip", ADHitch)
|
||||
addConsoleCommand("spuDetach", "Kobler redskaberne bag den maskine du sidder i af", "consoleDetach", ADHitch)
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<modDesc descVersion="107">
|
||||
<author>masterdraco</author>
|
||||
<version>1.47.0.0</version>
|
||||
<version>1.47.1.0</version>
|
||||
<title>
|
||||
<en>AD Smart Pickup</en>
|
||||
</title>
|
||||
|
||||
+17
-4
@@ -57,10 +57,23 @@ H.step(lostJob, {adActive = false, distance = 40, speed = 0}, 500, false)
|
||||
check("job: AD stoppede langt fra markøren", lostJob.state, "failed")
|
||||
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 route = H.parseTrip("Connect", "Bredal", ">", "Start", ">", "Afkobl", "Bredal", ">", "Start")
|
||||
check("tur: antal trin", #route, 4)
|
||||
check("tur: første", route[1], "Connect Bredal")
|
||||
check("tur: tredje", route[3], "Afkobl Bredal")
|
||||
check("tur: ét trin", #H.parseTrip("Start"), 1)
|
||||
check("tur: tomme trin droppes", #H.parseTrip("Start", ">", ">", "Stop"), 2)
|
||||
-- trin: handling pr. markør; almindelige markører = ankom (og vent, hvis ikke sidste)
|
||||
check("trin: connect", H.stepAction("Connect Bredal"), "attach")
|
||||
check("trin: afkobl", H.stepAction("Afkobl Bredal"), "detach")
|
||||
check("trin: almindelig", H.stepAction("Start"), "arrive")
|
||||
check("vent: mellem trin", H.waitAfter("arrive", 2, 4), H.ROUTE_WAIT_MS)
|
||||
check("vent: ikke efter sidste", H.waitAfter("arrive", 4, 4), 0)
|
||||
check("vent: ikke efter kobling", H.waitAfter("attach", 1, 4), 0)
|
||||
local arriveJob = H.newJob(1, "Start", "arrive")
|
||||
H.step(arriveJob, {adActive = false, distance = 1, speed = 0}, 250, false)
|
||||
H.step(arriveJob, {adActive = false, distance = 1, speed = 0}, 250, true)
|
||||
check("trin: ankom er færdig", arriveJob.state, "done")
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user