From bd47046ca8f5fbab8eede66eda93e9048686292f Mon Sep 17 00:00:00 2001 From: masterdraco Date: Fri, 25 Sep 2026 21:43:17 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20spec=20for=20markarbejde=20etape=201=20?= =?UTF-8?q?(sl=C3=A5afgr=C3=B8der=20via=20AutoDrive=20+=20Courseplay)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2026-09-25-markarbejde-etape1-design.md | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 docs/superpowers/specs/2026-09-25-markarbejde-etape1-design.md diff --git a/docs/superpowers/specs/2026-09-25-markarbejde-etape1-design.md b/docs/superpowers/specs/2026-09-25-markarbejde-etape1-design.md new file mode 100644 index 0000000..6097011 --- /dev/null +++ b/docs/superpowers/specs/2026-09-25-markarbejde-etape1-design.md @@ -0,0 +1,130 @@ +# Markarbejde, etape 1: slåafgrøder (græs, kløver, lucerne) + +Dato: 2026-09-25 · Mod: FS25_ADSmartPickup · Branch: `feature/markarbejde` + +## Mål + +Når en græs-, kløver- eller lucernemark er klar, sender Smart Pickup selv maskinerne ud. Slåmaskinen slår +marken via Courseplay. Ved **ensilage** samler en læssevogn skårene op og kører dem til den rigtige silo. +Ved **hø** vender en vender først græsset (og en river river det evt. sammen), og derefter samles høet op. +Alt kørsel på vej sker med AutoDrive. Alt arbejde på marken sker med Courseplay. + +Succes: en mark sat til *Auto* går fra "klar" til "færdig" med græsset i en silo, uden at spilleren rører +noget, og menuen viser hele tiden, hvad der sker og hvorfor. + +Ikke med i etape 1: mejetærskerafgrøder (etape 2), roer (etape 3), jordbehandling og såning, baller. + +## Arbejdsdeling + +| Del | Ansvar | +|---|---| +| **Smart Pickup (vores)** | Hvilken mark, hvilket trin, hvilken maskine, hvilken silo. Holder status og viser den | +| **AutoDrive** | Kørsel på vej til markens `F`-markør og til silo; overtager ved "vogn fuld" og genstarter Courseplay | +| **Courseplay** | Markgrænse, kursus, selve arbejdet på marken, "fuld"/"færdig"-signaler | + +## Beslutninger (med begrundelse) + +1. **Faste sæt.** Redskabet sidder fast på traktoren (eller er selvkørende, fx Krone BiG M 450). Mod'en + kobler aldrig redskaber på. *Begrundelse:* auto-påkobling var det, der aldrig blev pålideligt i AI-Bonden. +2. **Markflåde med forslag og flueben.** Mod'en foreslår sæt ud fra redskabets spec (`spec_mower`, + `spec_tedder`, `spec_windrower`, `spec_forageWagon`); kun sæt med flueben bliver sendt ud. + *Begrundelse:* mod'en må aldrig tage en maskine, spilleren selv bruger. Et sæt, spilleren sidder i + (`getIsControlled`/`getIsEntered`), springes altid over. +3. **Staging-markør pr. mark = AutoDrive-markør med navnet `F`** (fx `F109`), stort/småt + ligegyldigt, evt. med mellemrum (`F 109`). Mangler den, vises marken med "!" og sendes ikke ud. +4. **Auto/Manuel pr. mark.** Auto starter selv ved "klar"; Manuel venter på *Start nu*. Standard: Manuel + (intet sker uventet efter opdatering). +5. **Plan pr. mark: Ensilage eller Hø.** Standard: Ensilage. **Riv** er et valg pr. mark, standard *fra*: + læssevognene i Unrealistic Pack kan køre 40 m bredt og samler spredt hø op. +6. **Bredde.** Maskiner kører med deres *aktuelle* bredde (Unrealistic Packs `variableWorkWidth`, + `aiKeepCurrentWidth`). Courseplay kan højst 50 m → et sæt over 50 m sendes ikke ud (advarsel). + Marken husker **slåbredden**; opsamling/vending/rivning kræver bredde ≥ slåbredden, så hver bane + dækker det, slåmaskinen lagde. Så behøver banerne ikke flugte med skårene. +7. **Silovalg** genbruger Smart Pickups motor (`ADLoadSwap`): nærmeste silo med plads, der tager varen, + med vej fra `F`-markøren. *Tving lager* pr. mark (som "Lager til" i flows). Fabrikker er ikke mål. +8. **Marksilo.** En silo, hvis afstand til markens polygon er ≤ 150 m, er et mellemlager. Den må gerne + vælges (korte ture). Oversigten viser "!" ved marken, hvis intet Smart Pickup-udkørselsflow har + siloen som kilde — hjemkørslen klares af de eksisterende flows, ikke af markdelen. +9. **"Klar"** = ≥ 90 % af markens prøvepunkter står i høstvinduet for markens slåafgrøde + (`FSDensityMapUtil.getFruitArea`, samme metode som Arbejdsseddel, bevist i spillet). `field.fieldState` + bruges ikke (frossen NPC-plan for spillerejede marker). +10. **Slåafgrøde** afgøres ud fra spillets konvertere: `MOWER` giver et skår, og `TEDDER` gør skåret til en + `DRY…`-type (græs, lucerne, kløver, kløver2). Rug/bønner (→ halm) er udelukket. Ensilage-varen er + skåret (`GRASS_WINDROW` …), hø-varen er tørskåret (`DRYGRASS_WINDROW` …). +11. **Én maskine, én mark.** Flere marker kan køre samtidig. Højst 2 læssevogne pr. mark. +12. **Rækkefølge.** Næste trin starter først, når det forrige er *færdigt* på hele marken (ingen vender + bag slåmaskinen). Enklere og uden kollisioner mellem Courseplay-kurser. +13. **Fejl stopper ikke alt.** Kan Courseplay ikke lave kursus, prøves igen efter 5 min; imens står marken + med grunden. Andre marker kører videre. +14. **Genindlæsning.** Markernes trin gemmes i `ADSmartPickup_fields.xml` i savegame-mappen. Efter + indlæsning genoptages trinnet: sæt, der ikke længere kører, bliver sendt ud igen. + +## Opbygning + +Rene moduler (ingen spil-API, testes med `luajit`): + +| Fil | Ansvar | +|---|---| +| `adFieldModel.lua` | Mark-plan og -status som data: plan, tilstand, overgange (`nextStage`), bredde-regler, gem/indlæs-records | +| `adFieldFleet.lua` | Rolle ud fra redskabs-specs, forslag, valg af ledigt sæt (nærmest markøren) | +| `adFieldView.lua` | Rækker og tekster til fanen Marker (sortering, filtre, statusord) | + +Spil-moduler (tynde, pcall'ede): + +| Fil | Ansvar | +|---|---| +| `adFields.lua` | Ejede marker, polygon/prøvepunkter, afgrøde, klar-andel, `F`-markør, marksiloer | +| `adCpBridge.lua` | Start Courseplay på en mark (grænse → kursus → start, async med annullering), læs aktiv/færdig | +| `adFieldJobs.lua` | Tick hvert sekund: opdag klar, send sæt ud, følg ankomst → CP → færdig, næste trin, gem | +| `gui/SmartPickupFieldTab.lua` | Fanen **Marker**: tabel, detalje, markflåde | + +### Forløb pr. mark + +``` +Ensilage: idle → ready → mowing → collecting → done +Hø: idle → ready → mowing → tedding → [raking] → collecting → done +done → idle, når marken ikke længere er slået (vokser igen) +``` + +Hvert arbejdstrin har undertilstande pr. sæt: `driving` (AutoDrive til `F`) → `starting` (CP laver +kursus) → `working` (CP kører) → `returning` (AutoDrive til parkering). Trinnet er færdigt, når Courseplay +meldte færdig for mindst ét sæt, og intet sæt på marken stadig arbejder. + +**Slå/vende/rive:** AutoDrive `DRIVETO` til `F`-markøren. Ved stop inden for 30 m starter +`adCpBridge` Courseplay med `fieldPosition` = et prøvepunkt inde i marken. Når CP er færdig: AutoDrive +`DRIVETO` til sættets parkering (sættets AD-parkeringsmarkør, ellers bliver det stående ved `F`). + +**Opsamling:** Før CP startes sættes AutoDrive til `PICKUPANDDELIVER`, første markør = `F`, anden = +silo, `setStartHelper(true)` med hjælper Courseplay. Så klarer AutoDrive og Courseplay selv +fuld → aflæs → tilbage → `restartCP`. Ved CP færdig: AutoDrive tømmer resten (`enableParkAtJobFinished`) +og parkerer. + +## Fanen Marker + +- Tabel: **Mark · Afgrøde · Plan · Auto/Man. · Status · Maskiner**. Kun slåafgrøde-marker som standard + (*Vis alle marker* viser resten). Klik på en række → detalje. +- Detalje: Plan (Ensilage/Hø), Auto/Manuel, Riv, Tving lager (liste som "Lager til"), **Start nu**/**Stop**, + status med grund, markør og slåbredde. +- Markflåde: foreslåede sæt med flueben, rolle og aktuel bredde; advarsel over 50 m. +- Knapper på fanen: Start nu / Stop på valgt mark (samme placering som flows). +- Statusord: *Venter · Klar · Slås · Vendes · Rives · Samles op · Færdig* + grund ("venter på + slåmaskine", "! mangler markør F109", "læssevogn for smal: 20 m < 40,8 m", "Courseplay: intet kursus"). + +## Fejlhåndtering + +| Situation | Hvad sker | +|---|---| +| Ingen `F`-markør | "!" i tabellen, intet sendes | +| Intet ledigt sæt med rollen | Status "venter på …", prøver hvert 5 s | +| Sæt for bredt (> 50 m) eller for smalt (< slåbredde) | Sættet springes over med grund | +| AutoDrive kan ikke finde vej | Sættet frigives, status med grund, andet sæt prøves | +| CP-grænse/kursus fejler | 5 min pause for marken, grund vises | +| Spilleren sætter sig i et sæt | Sættet frigives fra marken (arbejdet fortsætter ikke automatisk) | +| Genindlæsning | Trin genoptages fra gemt fil | + +## Test + +- `tests/test_adFieldModel.lua`, `tests/test_adFieldFleet.lua`, `tests/test_adFieldView.lua`: alle + overgange, bredde-regler, forslag, sortering/filtre, gem/indlæs. +- In-game testprotokol (manualen + denne spec): én mark Manuel → Start nu → slå → saml op → silo, derefter + Hø, derefter Auto. Loglinjer: `ADSmartPickup: F109 …`.