feat(marker): sideriver — mål hvor riven lægger skåret, forskyd læssevognen tilsvarende (v1.24.0.0)

Brugerkrav 25/9: alle river-typer skal virke. Nedlægningsområdet (runtime-felt eller riverens XML) måles
i traktorens ramme mens riven arbejder; læssevognen på rivens kursus får CP-toolOffsetX = egen -
skårets forskydning og får sin værdi tilbage når den slippes.
This commit is contained in:
2026-09-25 23:35:42 +02:00
parent ba88eb5f99
commit cf7a2a51e5
13 changed files with 166 additions and 6 deletions
+27
View File
@@ -11,6 +11,8 @@ ADFieldJobs.ARRIVE_DISTANCE = 30
ADFieldJobs.IDLE_CONFIRM_MS = 5000
ADFieldJobs.START_TIMEOUT_MS = 60000
ADFieldJobs.PLAYER_DRIVING_KMH = 3
-- riven skal være udfoldet og i gang, før nedlægningsområdet måles
ADFieldJobs.WINDROW_MEASURE_MS = 10000
-- Courseplay kan efterlade hjørner på skæve marker: efter så mange færdige slå-ture går marken videre.
ADFieldJobs.MAX_MOW_PASSES = 2
ADFieldJobs.state = {fields = {}, fleet = {}, assignments = {}}
@@ -239,7 +241,16 @@ local function forgetFinished(fieldId)
ADFieldJobs.finished = remaining
end
-- Læssevognens oprindelige CP-forskydning sættes tilbage, når mod'en slipper den.
local function restoreToolOffset(assignment)
if assignment.restoreToolOffset ~= nil then
ADCpBridge.setToolOffset(assignment.vehicle, assignment.restoreToolOffset)
assignment.restoreToolOffset = nil
end
end
local function release(assignment, phase)
restoreToolOffset(assignment)
assignment.phase = phase or "released"
ADFieldJobs.state.assignments[assignment.vehicleId] = nil
end
@@ -317,6 +328,15 @@ local function beginWork(adEnv, field, info, assignment)
if source ~= nil and course == nil then
log(field.id, "intet %s-kursus kendt — Courseplay laver et nyt kursus til %s", source, assignment.role)
end
if source == "rake" and field.windrowOffset ~= nil and math.abs(field.windrowOffset) > 0.05 then
local own = ADCpBridge.getToolOffset(vehicle)
local target = ADFieldModel.collectorOffset(own, field.windrowOffset)
if ADCpBridge.setToolOffset(vehicle, target) then
assignment.restoreToolOffset = own
log(field.id, "skår ligger %.1f m %s for rivens linje -> læssevognens forskydning %.1f m (var %.1f m)",
math.abs(field.windrowOffset), field.windrowOffset > 0 and "til venstre" or "til højre", target, own)
end
end
local handle, err = ADCpBridge.start(vehicle, point.x, point.z, function(ok, reason)
if ok then
assignment.phase = "working"
@@ -382,6 +402,12 @@ local function follow(adEnv, assignment)
log(assignment.fieldId, "Courseplay svarede ikke inden 60 s")
end
elseif assignment.phase == "working" then
if assignment.role == "rake" and field.windrowOffset == nil and ADFieldJobs.now - assignment.since >= ADFieldJobs.WINDROW_MEASURE_MS
and ADCpBridge.isWorking(vehicle) then
local offset = ADCpBridge.getWindrowOffset(vehicle)
note(assignment.fieldId, {windrowOffset = offset or 0})
log(assignment.fieldId, offset ~= nil and "river lægger skåret %.1f m fra sin kursuslinje (venstre +)" or "river: nedlægningsområde ikke fundet — regner med midten (%.1f m)", offset or 0)
end
local busy = ADCpBridge.isWorking(vehicle) or isAdActive(vehicle)
if busy then
assignment.idleSince = nil
@@ -398,6 +424,7 @@ local function follow(adEnv, assignment)
log(assignment.fieldId, "%s '%s' færdig", assignment.role, ADRuns.vehicleLabel(vehicle))
local park = assignment.role ~= "collector" and parkMarkerId(adEnv, vehicle) or nil
if park ~= nil then startAd(adEnv, vehicle, adEnv.AutoDrive.MODE_DRIVETO, park, nil, false) end
restoreToolOffset(assignment)
assignment.phase = "finished"
ADFieldJobs.finished = ADFieldJobs.finished or {}
table.insert(ADFieldJobs.finished, assignment)