Skip to content

feat: per-axis RestTolerance in the options and the device settings (bug-034) - #9

Merged
rafalmaciag merged 2 commits into
masterfrom
feature/rest-tolerance
Oct 19, 2026
Merged

rafalmaciag merged 2 commits into
masterfrom
feature/rest-tolerance

Conversation

@rafalmaciag

Copy link
Copy Markdown
Contributor

What

  • RocketWelder.SDK.* PackageReferences 2.30.0 → 3.1.0 in the driver and the plugin. 3.1.0 is the release that adds ILinearAxis/IRotaryAxis.RestTolerance (rocket-welder-sdk#29).
  • GenericAxisOptions.RestTolerance (double, default DefaultRestTolerance = 0.1 per the bug-034 owner ruling of 2026-10-19). Validate() refuses a negative value or NaN, naming RestTolerance. 0 is allowed and means exact equality, for a drive that holds a quantised register.
  • ModbusLinearAxis / ModbusRotaryAxis take RestTolerance from _engine.Options.RestTolerance, the same way they do Tolerance.
  • One row in GenericAxisProperties.All, placed right after Tolerance. The label is Rest tolerance (mm|°) — allowed change between two capture readings, the type is double, the group is Motion, it is not required, and its default comes from the template (0.1). This row is what the rw2 device-settings dialog shows.
  • docs/protocol.md is unchanged. This is a rule for how the host reads positions, not a new register.

Tests

  • Options (GA-U-41): the default is 0.1; -0.1 and NaN are refused naming the field; 0 and 0.25 are accepted.
  • Property table (GA-U-43): the Values pin now covers the new row in table order. Binding gives 0.1 when the value is absent, and a stored 0 or 0.25 lands in the options. A stored -0.1 is refused by Validate, and the message names generic.axis.carriage.RestTolerance.
  • Declaration: the suffix, type and default sequence includes ("RestTolerance", "double", "0.1"). Labels are in mm and °, under the Motion heading.
  • Factory (GA-U-44): RestTolerance=-0.1 is refused naming the key. The built carriage reports 0.25 when stored and 0.1 when absent. The built turntable reports 0° when stored and 0.1° when absent.
  • The conformance and integration suites are untouched.

Local run of src/GenericAxis.sln:

  • Plugin.Tests: 70 passed, 0 failed.
  • GenericAxis.Tests: 210 passed, 0 failed.
  • TestApp.Tests: 260 of 261 passed. The one failure was GA_I_61_ASecondCtrlCDuringCleanupDoesNotAbortIt, which starts a child process with env dotnet, and dotnet is not on PATH on this host. With ~/.dotnet on PATH it passes.

🤖 Generated with Claude Code

https://claude.ai/code/session_014qfrwEnFVrCJNqiDqWFyb4

…bug-034)

GenericAxisOptions.RestTolerance (default 0.1, the owner ruling of 2026-10-19;
Validate refuses < 0 and NaN, 0 = exact equality) is reported by
ModbusLinearAxis/ModbusRotaryAxis as the SDK leaf's RestTolerance, and is one
row in GenericAxisProperties.All right after Tolerance, so it shows up in the
device settings dialog. RocketWelder.SDK.* 2.30.0 -> 3.1.0 (the release that
adds the member). Protocol unchanged: this is a host-side reading rule, not a
register.

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

@rafalmaciag rafalmaciag left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewer-ga: PR #9 (b129e20). Verdict: READY TO MERGE. No MUST findings; one SHOULD-level question for the lead, two COULDs.

What I checked: lead ruling item 2 in bug-034/dev-log.md, PRINCIPLES.md, standards/dotnet.md, the feature-007 design § GenericAxisOptions / § Plugin options table, test-scenarios GA-U-41/43/44, and generic-axis/CLAUDE.md.

  • SDK bump is complete. Driver ModelingEvolution.GenericAxis.csproj:20 and plugin ModelingEvolution.GenericAxis.Plugin.csproj:14-16 are all at 3.1.0. No csproj or props file still points at 2.30.0. src/Directory.Build.props is untouched.
  • The override mirrors Tolerance exactly. Linear ModbusLinearAxis.cs:55 (new(...), Length<double, Millimetre<double>>) and rotary ModbusRotaryAxis.cs:56 (Degree<double>.Create) do what lines 52/53 do. No unit conversion.
  • Validate matches the spec. GenericAxisOptions.cs:180 refuses negative values and NaN with ParamName RestTolerance. It accepts 0, and the default is 0.1. On a refusal, Bind goes through KeysFor, which names 'generic.axis.carriage.RestTolerance'. PropertyTableTests pins that message. The fallback 'generic.axis.carriage.*' would not match it, so the test can tell the two apart.
  • The row is right. In GenericAxisProperties.cs:128-132 the label is in mm for a linear axis and ° for a rotary one, the group is Motion, Required is false, the default is Num(o.RestTolerance) = "0.1", and the row sits directly after Tolerance.
  • GA-U-43 catches a missing or misplaced row. Values must Equal the order of All, and DeclarationTests pins the full suffix sequence.
  • The prefix handler covers the new key. GenericAxisPlugin.cs:73 → GenericAxisConfigKey.cs:64 registers every generic.axis.* key. A per-axis key needs no typed ConfigProperty.
  • docs/protocol.md is correct as it stands. RestTolerance is a reading rule on the host side, not a register. README.md and CLAUDE.md list no options.
  • Local runs (~/.dotnet/dotnet 10.0.401): GenericAxis.Tests 210/0, Plugin.Tests 70/0. I did not run TestApp.Tests locally. CI is green: test, conformance and python each passed on both runs.

[SHOULD — lead's call] GenericAxisOptions.cs:180: an infinite rest tolerance is accepted. !(RestTolerance >= 0) lets +∞ through, and ParseDouble("Infinity") parses. Once stored, the axis can never be refused, which goes against the owner ruling in the bug-034 report: "an axis that moves more than the setting … is still refused." The lead's spec says "≥ 0", and the PR implements that literally. This is not a MUST. Suggestion: if (!double.IsFinite(RestTolerance) || RestTolerance < 0), plus an InlineData for +∞ in OptionsAndHygieneTests. Tolerance (line 178) already had the same gap before this PR. Ref: standards/dotnet.md § "No Magic Strings - Fail Fast" (fail-fast on bad configuration).

[COULD] The "SDK 2.30.0" mentions are still true, but read as stale. They are at docs/protocol.md:161,168, MotionErrorClasses.cs:14 and python/generic_axis_check/errors.py:38. git diff v2.30.0 v3.1.0 -- csharp/RocketWelder.SDK.Devices.Motion touches only ILinearAxis.cs and IRotaryAxis.cs, so MotionError has not changed and the text is still correct. A reader on 3.1.0 may still wonder whether it was ever checked. Optional wording: "2.30.0 (unchanged through 3.1.0)". Ref: PRINCIPLES.md §0 Truth.

[COULD] PropertyTableTests.cs:79 (RestTolerance_Absent_BindsTheDefaultPointOne) duplicates existing tests. An_Absent_Value_Keeps_The_Driver_Default (:69) and Defaults_AreNamedSources already cover it. On its own it would also pass if the row were missing. The absent assertions in FactoryTests.cs:142,155 would pass with no override at all, because the SDK's default member also returns 0.1. This is not a defect: the stored halves (0.25, and 0 for the rotary axis) and the theory at :88 do tell a working override from a missing one. The redundant absent-only test could be deleted. Ref: standards/dotnet.md § "A test must distinguish 'correct' from 'nothing happened'"; PRINCIPLES.md §2.

Not a code finding: feature-007 design.md:76/:287 and test-scenarios GA-U-41/43 do not yet include RestTolerance. That is the doc-keeper follow-up the lead is carrying.

…plicate binding test (bug-034 review)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014qfrwEnFVrCJNqiDqWFyb4
@rafalmaciag
rafalmaciag merged commit 2d2da1d into master Oct 19, 2026
6 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.

1 participant