Skip to content

Sync pulverizador with official develop dac3bfd7 (#818-#834) - #227

Merged
renatorgr merged 38 commits into
pulverizadorfrom
sync-pulverizador
Nov 14, 2026
Merged

renatorgr merged 38 commits into
pulverizadorfrom
sync-pulverizador

Conversation

@renatorgr

Copy link
Copy Markdown
Owner

Requested by Renato · project thread

What changed

The daily sync of 14 November: official develop up to dac3bfd7 merged into pulverizador b9c15025.

From official:

Fork code adapted to AgOpenGPS-Official#831

Tool.HitchLength no longer exists, so the fork's own users of it now read RigGeometry.AttachX (the vehicle's hitch plus the tool's working point from it, + ahead of the rear axle), as the official tool position does:

  • the front implement round a bend (GpsPipelineService.FrontToolSteered, and its trigger now uses RigGeometry.Mount),
  • the S onto a line beside a hard fence (along in the side-step plan; a trailed implement stays at the drawbar pin),
  • the way to the start of the pass (frontReach in YouTurnCreationService.LineEntry).

The fork's tests set the vehicle's hitch the way official migrated its own (ThreePointHitchLength = FrontHitchLength = |h|, WorkingPointFromHitch = 0).

Conflicts:

File Resolution
GpsPipelineService.cs Fork: the lateral-move toast and the hard-fence refusal; the fork's duplicate PassName dropped (official's kept).
YouTurnStateMachine.cs Both fields (_loggedAbHeading, fork _plannedSameWay), official comments.
YouTurnCreationService.cs, .Orchestration.cs Fork: gapResumeIndex, the slide bound, obstacle fallback; official's wording for TurnLineEndOnRetry.
CurveProcessing.cs, YouTurnCreationInput.cs Official (comments only; the fork's PassUnfit stays).
SceneProjector.cs Both: the fork's RtkHold in the config stamp and official's two new hitch lengths.
frame.js, map-draw.js Fork: boundary ring selection, the line-entry path, guidelines only where they enter the field; official's guard on extendAbLine.
en.json Both.
CLAUDE.md Fork bullets; the front implement section names RigGeometry.AttachX.
ClosedPassSeamTests.cs, ClosedPassSeamPipelineTests.cs, TurnSetbackStaysAtEndTests.cs, HeadlandToggleTests.cs Official (our tests upstreamed, with the hitch model).
LateralMoveTests.cs Fork (it also checks the toast).

Related issue

None.

Pre-submit checklist

  • dotnet build succeeds with no errors (Desktop, every test and harness project)
  • dotnet test: Models 499, ViewModels 767, RemoteServer 44 passed; Services: the 226 tests of the touched areas (front implement, side step, hard fence, line entry, manual U-turn by a hard fence, obstacle U-turns, setback, lateral move, closed passes, headland toggle, end of pass, snake, open curves, rig geometry) passed. The full Services run is left to CI.
  • Tools/i18n-extract.py --check and Tools/license-headers.py --check pass
  • Tested on: not on hardware. Not in a beta until one is built by hand. After it: check the vehicle's hitch lengths and the tool's working point in the settings (profiles are migrated, the Puma's front boom should still be 4.5 m ahead of the rear axle).

Generated by Claude Code

claude and others added 30 commits November 12, 2026 16:48
A closed Boundary Curve (2,249 points) with 10 extra guidelines each side
drew at 7 fps on an Intel HD 4000 (109 ms a frame): the screen froze and the
page missed its presence heartbeat (AutoSteer off, deadman).

- Extra guidelines go in one path, stroked once with the shadow and once
  with the green (was 2 strokes per line, 40 screen-sized masks a frame).
- Scene lines are drawn from a copy without points within 2 mm of their
  neighbours (Douglas-Peucker, cached per array), then within 0.25 px on
  the screen every frame.
- The tool band's edges are made once per pass, each point is projected
  once, and quads off the screen are left out.

No visible change. Client only; the host's hot paths are untouched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKEBDGviRvcfDmKpDsRru9
The pipeline holds the last headland distance so the box doesn't vanish
between crossing the headland line and the U-turn. It held it with the
headland turned off too: there is no distance then (AgOpenGPS draws the box
only with the headland on, and the host sends none), so the last one stayed
on the screen, frozen while the tractor drove on, until the headland was
turned on again. A tester's box stood at 173 m for 55 s on Tapada da Casa.

The hold now needs the headland on, and the held value is dropped when
there is none to show (headland off, no headland line).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKEBDDYnkAJhx49ZdYtRAu
A closed curve's last point repeats its first, so the offset moved the
seam's point twice: along the last stretch's normal and along the
first's. On the inside of the seam's bend the second copy lay
2·d·tan(θ/2) behind the first (0.21 m on a 26 m lap of a round field):
the pass ran on past the seam and back, its closing stretch pointing
backwards. A tractor engaged 0.4 m off the line at the seam was steered
to a goal behind it and turned round. On the inside the repeated point
is now left out, so the pass goes from the last stretch's offset
straight to the first's, as at any inside bend; on the outside it
starts the arc round the seam, as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKEBDDmANdNEsud9B3UMsp
…n test

The arc that closes a loop at its seam (AgOpenGPS-Official#450) was the one arc whose
points skipped the collision test every other arc point goes through.
With the seam at the tip of a narrow slot into the field (its sides
closer than twice the offset), the test removed the pass's points along
both sides of the slot, and the untested arc put the whole way round
the tip into the pass: out across the fence beyond it (8.7 m on a 12 m
lap in the test, 8.4 m on the job harness's Couto Ribeira lap 2), back
across the pass, so the pass crossed itself. AutoSteer engaged near the
crossing could take the other leg and turn round. Now the seam's arc is
tested like the others, and the pass at the seam is the same as
anywhere else on the loop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKEBDDmANdNEsud9B3UMsp
…ve-draw-cost-upstream

Web map: long curves cost less to draw (older PCs froze)
…-distance-off-upstream

Headland distance box: no held value with the headland off
…ng day reports

Those two harnesses list findings as a table, not the numbered list the parser read, so a
fix-vs-base compare of them said '0 new, 0 gone, 0 in both' with findings on both sides.
Columns are found by their header; the scenarios column gives the count.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…/compare-table-reports

compare-reports: read the web client and working day findings tables
…kept

- The metadata feature carries formatVersion (1; none reads as 1). Adding a role or a
  property doesn't change it; a change of meaning raises it.
- A field in a newer format is read but never written: every save of field.geojson
  leaves such a file alone, and opening it tells the operator changes aren't saved.
- Each part (field metadata, boundaries, headland, tracks, flags, headland lines,
  background) keeps the properties of its feature that this build doesn't read and
  writes them back; a property it reads is never kept as unknown. Members of the
  collection and of features beyond type/geometry/properties are kept too.
- FIELD_FILE_FORMATS.md: the version and the rules.

Before: a newer build's (or another tool's) property on a track, boundary or flag was
dropped the next time this build saved that part.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- job.json keeps members this build doesn't read and writes them back; a status it
  doesn't know reads as InProgress (it used to make the job unreadable, so it dropped
  out of the job list).
- A job whose job.json or coverage manifest is in a newer version is listed but never
  written: its coverage isn't loaded or saved, and the operator is told to start a new
  job. Before, a newer manifest failed validation, was set aside as damaged, and the
  next save replaced it and deleted the tiles it didn't know.
- FIELD_FILE_FORMATS.md: the rules for job.json and the manifest.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A bug report showed the guidance line one pass over with the tractor
standing still, and nothing in its log said why: a lateral move (the
lateral buttons, the nudge flyout's Pass buttons) was not logged. Each
one is now logged ("[Guidance] Lateral move right: pass 19R -> 20R"),
and one ignored while a U-turn is driven too.

The YouTurn "AB Line: abHeading" debug line was written on every 30th
count of the U-turn counter: in that report it was 1273 of the 2000
lines a bug report keeps, so the log reached back only 21 minutes. It
is now written when the heading changes (19 lines a minute -> 1 in
AbHeadingLogTests).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKEBDGCt1N7D8a1xv5HtTx
When the implement would cross a hard outer boundary in the turn,
CreateTurnPath tries again with the whole fence's turn line moved in
(extraSetback). Where the fence comes in beside the pass, the moved
line also crosses the pass there, long before the end, and
FindCurveTurnPoint took that first crossing ahead: on a real field an
8 m front boom near the fence at the far end turned 260 m before the
end of its pass, and the strip it left on the next pass was never
sprayed.

The first try's end (the pass's first point outside the turn area) is
passed to the tries that follow (YouTurnCreationInput.TurnLineEndIndex);
they walk back from it to the moved line's crossing nearest to it
(TurnLineEndOnRetry) instead of searching ahead from the tractor.
TurnSetbackStaysAtEndTests: an 8 m boom ahead of the pivot and one
behind it, the fence coming in to 5 m from the pass for 30 m: the turn's top was at
y -23.5 / -22.0, beside the narrowing; now 92.8 / 93.8, as on the same
field without it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKEBDGCt1N7D8a1xv5HtTx
…/field-format-version

Field, job and coverage files: a format version, and what this build doesn't read is kept
…fails

The field job harness has six fixtures and they all wrote the one /out/report.md: the last one
run overwrote the others, so a comparison of P1 or J7 read the turn-intervention report and said
"0 new, 0 gone" about jobs it never saw.

- Tests/ScenarioShared/ReportPath.cs, linked into every harness: AGOPENWEB_SCENARIO_REPORT (and
  AGOPENWEB_DAY_REPORT) may name a folder; each report goes in under its own name.
- A field job fixture with none of AGOPENWEB_SCENARIO_ONLY's jobs writes no report (ignored).
- run-harness.sh points the reports at /out/ (a ref from before keeps /out/report.md).
- runner-compare.sh compares every report by name and exits 1 when a side did not pass, a report
  is on one side only, there is none, or an old ref ran several fixtures into one report.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…OB-NEVER-TURNED)

The operator taking over at a blocked U-turn was noted as what the app must do, and every
coverage check passed on nothing sprayed: J7 and W2 sprayed 0 % in every nightly since at least
2026-11-11 with the run green. A takeover before any U-turn is now a Bug, unless the turn was
refused (TURN-REFUSED already) or there was no room on the next pass (the end of the field).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ass-seam-upstream

Closed curve passes: no turn-round or crossing at the seam
…tback-end-of-pass-upstream

U-turn tried again off a hard fence stays at the end of the pass
…ral-moves-upstream

Log each lateral move, and the AB line's heading only when it changes
…/runner-report-per-fixture

Runner compare: every fixture's report; a job that never turned is a finding
…lace

Phase 1 of the hitch model (AgOpenGPS-Official#547): today's model, the tool where it was. The tool position, the
map's implement (the render pull), the U-turn's swept path, its tool geometry and the key of a
remembered U-turn end each had their own copy of the hitch branch, and the copies differed on
which flag won when a profile set two (front and rear, front and trailing). They all read
RigGeometry now (Mount, AttachX, AlongTractor, ToolBehindPivot, TrailedToolCentre, Geometry,
Stamp), with x along the tractor from the rear axle, + ahead (ISO 11783-10's device axes).

Behaviour: none for a tool with one type flag (RigGeometryTests: all 16 flag combinations
against the old formula). With no flag set the tool is the default rear-fixed one (the old copy
put the tractor's hitch pin ahead of the axle). The settings panel's type and the status text
show the mount in use (the status text now names TBT). The remembered U-turn end is also
forgotten when the trailing hitch, pivot or tank distances or the mount change (it watched only
some of them).

A source scan keeps hitch branches out of the files that place the tool.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…actor/rig-geometry

RigGeometry: where the tool hangs on the tractor, worked out in one place
…s distance from its hitch

AgOpenGPS-Official#547, phase 2 of NonTracked/HITCH_MODEL_PLAN.md, after ISO 11783-10 (a device's connectors from
its reference point, the tractor's rear axle; its elements from them). A fixed tool was placed
by one number per tool, rear axle -> working point, so a tool profile was right only on the
tractor it was measured on.

- Vehicle: HitchLength (the drawbar pin, as before), ThreePointHitchLength (rear 3-point, the
  centre of the lower links) and FrontHitchLength (front 3-point; asked for only with a front tool).
- Tool: WorkingPointFromHitch replaces HitchLength: the working point from its 3-point hitch,
  away from the tractor, negative on the tractor's side. RigGeometry chains them.
- Profiles format 3. A format-2 tool is converted against the vehicle loaded with it so it stays
  exactly where it was (a format-2 vehicle's 3-point starts at its one hitch; a front tool gives a
  vehicle without a front hitch its value), and both files are saved at once. Format 3 still
  writes the axle -> working point as hitchLength for an older build; a profile from a newer
  build is not overwritten.
- AgOpenGPS import: the tractor's 3-point and front hitch from the rear- and front-mounted
  implements saved last (as the drawbar from the trailed one), each fixed implement its
  AgOpenGPS distance less that hitch: every implement where AgOpenGPS has it.
- Settings: Vehicle > Rear 3-point hitch, Drawbar pin, Front 3-point hitch (with a front tool);
  Tool > Hitch to working point, with the sum from the rear axle.
- Harnesses send a fixed implement as the tractor's hitch with the implement at it (the same
  place); the careless operator's mounted-distance mistakes go to the 3-point hitch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…axle on every build

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t/hitch-model

Hitch model: the tractor's hitch points on the vehicle, a fixed tool's distance from its hitch
…ed tool's from them

The rear and front tool pictures measured from the rear axle to the working point, the
old single value; since AgOpenGPS-Official#547 the tool's field is the distance from the 3-point lower-link
pins. The vehicle's hitch picture now follows the field being typed in (rear 3-point,
drawbar pin, front 3-point), else the hitch the tool hangs on. A test checks that every
picture the web client names is in wwwroot/icons.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t/hitch-diagrams

Hitch diagrams: the vehicle's distances to its lower-link pins, a fixed tool's from them
Updated by "Cleanup translation files" add-on in Weblate.

Translation: AgOpenGPS/AgOpenWeb
Translate-URL: https://hosted.weblate.org/projects/agopengps/agopenweb/
Updated by "Cleanup translation files" add-on in Weblate.

Translation: AgOpenGPS/AgOpenWeb
Translate-URL: https://hosted.weblate.org/projects/agopengps/agopenweb/
Updated by "Cleanup translation files" add-on in Weblate.

Translation: AgOpenGPS/AgOpenWeb
Translate-URL: https://hosted.weblate.org/projects/agopengps/agopenweb/

Translated using Weblate (German)

Currently translated at 90.4% (1022 of 1130 strings)

Translation: AgOpenGPS/AgOpenWeb
Translate-URL: https://hosted.weblate.org/projects/agopengps/agopenweb/de/
Updated by "Cleanup translation files" add-on in Weblate.

Translation: AgOpenGPS/AgOpenWeb
Translate-URL: https://hosted.weblate.org/projects/agopengps/agopenweb/
weblate and others added 8 commits November 14, 2026 00:41
Updated by "Cleanup translation files" add-on in Weblate.

Translation: AgOpenGPS/AgOpenWeb
Translate-URL: https://hosted.weblate.org/projects/agopengps/agopenweb/
Updated by "Cleanup translation files" add-on in Weblate.

Translation: AgOpenGPS/AgOpenWeb
Translate-URL: https://hosted.weblate.org/projects/agopengps/agopenweb/
Updated by "Cleanup translation files" add-on in Weblate.

Translation: AgOpenGPS/AgOpenWeb
Translate-URL: https://hosted.weblate.org/projects/agopengps/agopenweb/
Updated by "Cleanup translation files" add-on in Weblate.

Translation: AgOpenGPS/AgOpenWeb
Translate-URL: https://hosted.weblate.org/projects/agopengps/agopenweb/
…ts and the chain of tools

job.json gains rig: the vehicle's connectors and the tools in order from it, each measured from
the connector it hangs on (ISO 11783-10), a copy of the loaded profiles taken when the job starts
or resumes and whenever a profile is loaded or saved, written only when it changed. The web
client keeps one tool, so AgOpenWeb writes a chain of one; the format takes more. A new member,
so schemaVersion stays 1 (AgOpenGPS-Official#547).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…gps-agopenweb

Translations update from Hosted Weblate
…t/job-rig

Jobs keep the machine they were worked with: the vehicle's hitch points and the chain of tools
…cial#834) into sync-pulverizador

Conflicts:
- Fork PRs that went upstream (AgOpenGPS-Official#818 long-curve draw cost, AgOpenGPS-Official#819 headland
  distance, AgOpenGPS-Official#821 closed-pass seam, AgOpenGPS-Official#827 lateral-move log, AgOpenGPS-Official#828 U-turn setback
  at the pass end): official wording and tests, fork extras kept (the
  lateral-move toast and hard-fence refusal, gapResumeIndex, the slide bound,
  boundary ring selection, the line-entry path, guidelines that enter the field).
- SceneProjector config stamp: the fork's RtkHold with official's hitch lengths.
- en.json: both. CLAUDE.md: fork bullets.

Official AgOpenGPS-Official#831 (hitch model) removed Tool.HitchLength: the fork's front implement
round a bend, the S onto a line beside a hard fence and the way to the start of
the pass now read RigGeometry.AttachX (the vehicle's hitch plus the tool's working
point from it), and the fork's tests set the vehicle's hitch as official's do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKEBDGFo85z1i7tUm4kacp
@renatorgr renatorgr self-assigned this Nov 14, 2026
@renatorgr
renatorgr marked this pull request as ready for review November 14, 2026 06:48
@renatorgr
renatorgr merged commit 2be8132 into pulverizador Nov 14, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants