feat(marker): halm efter høst — hakkes, samles op til silo eller presses til baller + ballesamler (CP BALE_FINDER); græsvalg også ved græs-mål

This commit is contained in:
2026-09-26 01:26:35 +02:00
parent af71548b0b
commit 293d66156f
10 changed files with 198 additions and 16 deletions
+18 -7
View File
@@ -28,7 +28,7 @@ ADFieldModel.ROLES = {
mowing = "mower", tedding = "tedder", raking = "rake", collecting = "collector",
harvesting = "harvester", mulching = "mulcher", liming = "limer", plowing = "plow",
cultivating = "cultivator", sowing = "seeder", rolling = "roller", weeding = "weeder",
fertilizing = "fertilizer",
fertilizing = "fertilizer", strawCollecting = "collector", baling = "baler", baleCollecting = "baleCollector",
}
ADFieldModel.HELPERS = {harvesting = "unloader"}
ADFieldModel.CARE_STAGES = {fertilizing = true, weeding = true, careLiming = true}
@@ -42,8 +42,11 @@ KNOWN_STAGES.careLiming = true
local DEFAULT_PLAN = {
mode = "manual", product = "auto", rake = false, rigs = 1, unloaders = 1,
mulch = false, lime = true, soil = "auto", sow = false, sowFruit = "", roll = false,
fertilize = true, weed = true, targetFruit = "", prepAfterMow = false,
fertilize = true, weed = true, targetFruit = "", prepAfterMow = false, straw = "chop",
}
local STRAW_VALUES = {chop = true, collect = true, bale = true}
-- halm-trin efter høst (mejetærskeren lægger skår når halmen skal bruges)
local STRAW_STAGES = {collect = {"strawCollecting"}, bale = {"baling", "baleCollecting"}}
local SOIL_VALUES = {auto = true, cultivate = true, plow = true, none = true}
local PRODUCTS = {auto = true, silage = true, hay = true, harvest = true}
@@ -116,6 +119,7 @@ function ADFieldModel.workStages(plan, kind, needs)
local product = ADFieldModel.product(plan, kind)
if product == "harvest" then
local stages = {"harvesting"}
for _, stage in ipairs(STRAW_STAGES[plan.straw or "chop"] or {}) do table.insert(stages, stage) end
for _, stage in ipairs(ADFieldModel.prepStages(plan, needs)) do table.insert(stages, stage) end
return stages
end
@@ -168,9 +172,10 @@ function ADFieldModel.shouldStartBare(field, kind, plantableNow)
return plantableNow == true
end
-- Krævet bredde for et sæt: kun læssevognen uden riv skal dække slåmaskinens baner.
-- Krævet bredde for et sæt: kun læssevognen uden riv skal dække slåmaskinens baner (halmskår ligger i
-- høsterens spor — der er breddekravet ligegyldigt).
function ADFieldModel.requiredWidth(field, role)
if role == "collector" and not field.plan.rake then
if role == "collector" and not field.plan.rake and field.stage ~= "strawCollecting" then
return field.mowWidth
end
return nil
@@ -178,6 +183,8 @@ end
-- Hvilket tidligere kursus sættet skal køre: læssevognen følger skårene; de andre laver deres eget.
function ADFieldModel.courseSource(field, role)
-- halm: læssevogn og presser kører høsterens kursus (skåret ligger i mejetærskerens spor)
if field.stage == "strawCollecting" or role == "baler" then return "harvester" end
if role ~= "collector" then return nil end
return field.plan.rake and "rake" or "mower"
end
@@ -247,6 +254,7 @@ local function freshCycle(copy)
copy.mowWidth = nil
copy.mowVehicleId = nil
copy.rakeVehicleId = nil
copy.harvestVehicleId = nil
copy.windrowOffset = nil
copy.careRuns = {}
end
@@ -276,7 +284,7 @@ function ADFieldModel.advance(field, needs)
local stages = ADFieldModel.workStages(field.plan, field.kind, needs)
copy.stage = "done"
local passed = false
local order = {"mowing", "tedding", "raking", "collecting", "harvesting", "mulching", "liming", "plowing", "cultivating", "sowing", "rolling"}
local order = {"mowing", "tedding", "raking", "collecting", "harvesting", "strawCollecting", "baling", "baleCollecting", "mulching", "liming", "plowing", "cultivating", "sowing", "rolling"}
local rank = {}
for index, stage in ipairs(order) do rank[stage] = index end
for _, stage in ipairs(stages) do
@@ -303,7 +311,7 @@ end
-- Vejrfølsomme trin: afgrøde og skår skal være tørre (høst, slåning, vending, rivning, hø-opsamling).
-- Jordbehandling, såning, pleje og ensilage-opsamling kan køre i regn.
local WEATHER_STAGES = {harvesting = true, mowing = true, tedding = true, raking = true}
local WEATHER_STAGES = {harvesting = true, mowing = true, tedding = true, raking = true, strawCollecting = true, baling = true}
function ADFieldModel.isWeatherSensitive(stage, plan, kind)
if WEATHER_STAGES[stage] then return true end
return stage == "collecting" and ADFieldModel.product(plan, kind or "mowable") == "hay"
@@ -423,11 +431,12 @@ function ADFieldModel.toRecord(field)
rigs = plan.rigs, unloaders = plan.unloaders, mulch = flag(plan.mulch), lime = flag(plan.lime),
soil = plan.soil, sow = flag(plan.sow), sowFruit = plan.sowFruit or "", roll = flag(plan.roll),
fertilize = flag(plan.fertilize), weed = flag(plan.weed),
targetFruit = plan.targetFruit or "", prepAfterMow = flag(plan.prepAfterMow),
targetFruit = plan.targetFruit or "", prepAfterMow = flag(plan.prepAfterMow), straw = plan.straw or "chop",
kind = field.kind or "", lastFruit = field.lastFruit or "", care = table.concat(care, " "),
mowWidth = field.mowWidth or 0,
mowVehicle = field.mowVehicleId or "",
rakeVehicle = field.rakeVehicleId or "",
harvestVehicle = field.harvestVehicleId or "",
windrowOffset = field.windrowOffset ~= nil and string.format("%.2f", field.windrowOffset) or "",
}
end
@@ -462,12 +471,14 @@ function ADFieldModel.fromRecord(record)
plan.weed = readFlag(record.weed, true)
plan.targetFruit = record.targetFruit or ""
plan.prepAfterMow = readFlag(record.prepAfterMow, false)
plan.straw = STRAW_VALUES[record.straw] and record.straw or "chop"
field.kind = readText(record.kind)
field.lastFruit = readText(record.lastFruit)
for stage, runs in string.gmatch(record.care or "", "(%w+)=(%d+)") do field.careRuns[stage] = tonumber(runs) end
field.mowWidth = (record.mowWidth or 0) > 0 and record.mowWidth or nil
field.mowVehicleId = readText(record.mowVehicle)
field.rakeVehicleId = readText(record.rakeVehicle)
field.harvestVehicleId = readText(record.harvestVehicle)
field.windrowOffset = tonumber(record.windrowOffset)
return field
end