feat(focas): scale axis positions by 10^PositionDecimalPlaces (config-supplied)

This commit is contained in:
Joseph Doherty
2026-06-16 05:32:36 -04:00
parent fcb3801415
commit 4973075291
4 changed files with 182 additions and 9 deletions
@@ -109,10 +109,27 @@ public sealed class FocasAlarmProjectionOptions
/// address validation at <c>FocasDriver.InitializeAsync</c>; leave as
/// <see cref="FocasCncSeries.Unknown"/> to skip validation (legacy behaviour).
/// </summary>
/// <param name="PositionDecimalPlaces">
/// Axis positions returned by <c>cnc_rddynamic2</c> are scaled integers. The driver
/// divides AbsolutePosition / MachinePosition / RelativePosition / DistanceToGo by
/// <c>10^PositionDecimalPlaces</c> at the publish seam so they surface in engineering
/// units on the Float64 axis nodes. Default <c>0</c> (no scaling) is byte-identical to
/// legacy behaviour. Auto-fetching this via <c>cnc_getfigure</c> is deferred (wire-gated),
/// so it is config-supplied. Negative values are clamped to 0 (no scaling).
/// </param>
public sealed record FocasDeviceOptions(
string HostAddress,
string? DeviceName = null,
FocasCncSeries Series = FocasCncSeries.Unknown);
FocasCncSeries Series = FocasCncSeries.Unknown,
int PositionDecimalPlaces = 0)
{
/// <summary>
/// Axis-position decimal places, clamped to a non-negative value so the
/// <c>10^PositionDecimalPlaces</c> divide at the publish seam can never misbehave.
/// </summary>
public int PositionDecimalPlaces { get; init; } =
PositionDecimalPlaces < 0 ? 0 : PositionDecimalPlaces;
}
/// <summary>
/// One FOCAS-backed OPC UA variable. <paramref name="Address"/> is the canonical FOCAS