Table of Contents

Class ReferenceReturnSyntax

Namespace
Hi.NcParsers.LogicSyntaxs
Assembly
HiMech.dll

Writes ICompoundMotionDef section for G28 reference point return. Reads intermediate XYZ from Parsing.G28 (written by G28Syntax) and converts to machine coordinates via ResolveProgramXyz(JsonNode, LazyLinkedListNode<SyntaxPiece>, ISentenceCarrier, NcDiagnosticProgress).

Must be placed after LinearMotionSyntax in the syntax chain. Removes the IMotionEventDef section written by LinearMotionSyntax (G28 handles its own motion). Overwrites root MachineCoordinateState and ProgramXyz with reference position for subsequent block lookback.

public class ReferenceReturnSyntax : ISituNcSyntax, INcSyntax, IMakeXmlSource
Inheritance
ReferenceReturnSyntax
Implements
Inherited Members
Extension Methods

Examples

All cases hardcode a TestDeps.HomeMc with X/Y home at 0 and Z home at 100 (typical mill where Z-home is above the table) and leave the ProgramToMcTransform chain at identity so the final ProgramXyz equals MachineCoordinateState. The G28 pattern emits a 2-item CompoundMotion: item 0 is the intermediate point in ProgramXyz, item 1 is the final position in MachineCoordinateState. Axes not present in the G28 block keep the previous-block MC value rather than going home.

G91 G28 X0 Y0 Z0 with a #Previous: block carrying MachineCoordinateState=(50,60,70) — all three axes go home, so the final MC is the configured home (0,0,100):

#Previous:
{ "MachineCoordinateState": { "X": 50, "Y": 60, "Z": 70 } }
#BeforeBuild:
{ "Parsing": { "G28": { "X": 0, "Y": 0, "Z": 0 } } }
#AfterBuild:
{
  "CompoundMotion": {
    "Term": "G28",
    "Items": [
      {
        "MotionEvent": { "Form": "McLinear", "IsRapid": true },
        "ProgramXyz": { "X": 0, "Y": 0, "Z": 0 }
      },
      {
        "MotionEvent": { "Form": "McLinear", "IsRapid": true },
        "MachineCoordinateState": { "X": 0, "Y": 0, "Z": 100 }
      }
    ]
  },
  "ProgramXyz": { "X": 0, "Y": 0, "Z": 100 }
}
G91 G28 Z0 — only Z goes to its home; X/Y inherit from the previous block's MC. Item 0's intermediate ProgramXyz takes X/Y from the inherited program XYZ (= previous MC under identity transform) and Z from the literal 0 in the G28 block: #Previous:
{ "MachineCoordinateState": { "X": 50, "Y": 60, "Z": 70 } }
#BeforeBuild:
{ "Parsing": { "G28": { "Z": 0 } } }
#AfterBuild:
{
  "CompoundMotion": {
    "Term": "G28",
    "Items": [
      {
        "MotionEvent": { "Form": "McLinear", "IsRapid": true },
        "ProgramXyz": { "X": 50, "Y": 60, "Z": 0 }
      },
      {
        "MotionEvent": { "Form": "McLinear", "IsRapid": true },
        "MachineCoordinateState": { "X": 50, "Y": 60, "Z": 100 }
      }
    ]
  },
  "ProgramXyz": { "X": 50, "Y": 60, "Z": 100 }
}
No IHomeMcConfig dep on the dependency list — the syntax early-returns and the G28 sub-section stays in Parsing for an upstream consumer or downstream syntax to handle: #BeforeBuild:
{ "Parsing": { "G28": { "X": 0, "Y": 0, "Z": 0 } } }
#AfterBuild:
{ "Parsing": { "G28": { "X": 0, "Y": 0, "Z": 0 } } }

Rotary cases below add TestDeps.AxisConfig declaring B as rotary and extend HomeMc with the conventional B home at 0°. Each rotary block uses literal B = 45° so item 0's intermediate (45°), item 1's home (0°), and #Previous: modal B (30°) are pairwise distinct — a test that swaps any two values for any other is caught by the assertion. The wrap pass (McAbcCyclicPathSyntax) is a different syntax, so these per-SUT conformance assertions show only the raw literal / canonical-home values written by this syntax, before any cyclic normalization runs.

G91 G28 B45. — pure rotary G28. Emits a 2-item CompoundMotion whose items carry only ABC keys in MC; no XYZ ProgramXyz and no XYZ MC because the block doesn't reference X/Y/Z (and the conformance harness doesn't run McXyzSyntax downstream — in the full pipeline that syntax fills root MachineCoordinateState's XYZ from root ProgramXyz, but with no XYZ in the block there's nothing to fill anyway). Root MC.B holds the canonical home for modal carry-forward; root ProgramXyz is not written: #BeforeBuild:
{ "Parsing": { "G28": { "B": 45 } } }
#AfterBuild:
{
  "MachineCoordinateState": { "B": 0 },
  "CompoundMotion": {
    "Term": "G28",
    "Items": [
      {
        "MotionEvent": { "Form": "McLinear", "IsRapid": true },
        "MachineCoordinateState": { "B": 45 }
      },
      {
        "MotionEvent": { "Form": "McLinear", "IsRapid": true },
        "MachineCoordinateState": { "B": 0 }
      }
    ]
  }
}
G28 X0. B45. mixed XYZ + rotary. Both axis kinds occupy the same two items: item 0 carries the XYZ intermediate ProgramXyz alongside the rotary literal in MC; item 1 carries the final XYZ MC alongside the rotary home in MC. Root MachineCoordinateState here holds only the rotary modal value (B = 0, the home); the XYZ portion of root MC would be filled by the downstream McXyzSyntax in the full pipeline (out of scope for this per-SUT conformance). Root MachineCoordinateState appears first because the rotary-home write happens before CompoundMotion / ProgramXyz are inserted. #Previous: carries B = 30 so the prev rotary modal is distinct from both the literal (45) and the home (0): #Previous:
{ "MachineCoordinateState": { "X": 50, "Y": 60, "Z": 70, "B": 30 } }
#BeforeBuild:
{ "Parsing": { "G28": { "X": 0, "B": 45 } } }
#AfterBuild:
{
  "MachineCoordinateState": { "B": 0 },
  "CompoundMotion": {
    "Term": "G28",
    "Items": [
      {
        "MotionEvent": { "Form": "McLinear", "IsRapid": true },
        "ProgramXyz": { "X": 0, "Y": 60, "Z": 70 },
        "MachineCoordinateState": { "B": 45 }
      },
      {
        "MotionEvent": { "Form": "McLinear", "IsRapid": true },
        "MachineCoordinateState": { "X": 0, "Y": 60, "Z": 70, "B": 0 }
      }
    ]
  },
  "ProgramXyz": { "X": 0, "Y": 60, "Z": 70 }
}

Bare G28 — no axis specifiers — exercises the configurable BareG28 policy. Default Alarm emits Coord-RefReturn--003 and consumes the G28 without motion (the diagnostic surfaces through the NcDiagnosticProgress sink, not the block JSON, so the canonical #AfterBuild is just an empty object):

#BeforeBuild:
{ "Parsing": { "G28": {} } }
#AfterBuild:
{}
Bare G28 with BareG28 set to AllAxesHome: the syntax synthesises a literal at the inherited program position for every configured linear axis and the previous modal angle for every configured rotary axis (here X/Y/Z taken from the #Previous: MC under the identity ProgramToMcTransform, B taken from the prev modal). Item 0's intermediate therefore equals current (no motion in stage 1) and item 1 sends each axis to its home: #Previous:
{ "MachineCoordinateState": { "X": 10, "Y": 20, "Z": 30, "B": 45 } }
#BeforeBuild:
{ "Parsing": { "G28": {} } }
#AfterBuild:
{
  "MachineCoordinateState": { "B": 0 },
  "CompoundMotion": {
    "Term": "G28",
    "Items": [
      {
        "MotionEvent": { "Form": "McLinear", "IsRapid": true },
        "ProgramXyz": { "X": 10, "Y": 20, "Z": 30 },
        "MachineCoordinateState": { "B": 45 }
      },
      {
        "MotionEvent": { "Form": "McLinear", "IsRapid": true },
        "MachineCoordinateState": { "X": 0, "Y": 0, "Z": 100, "B": 0 }
      }
    ]
  },
  "ProgramXyz": { "X": 0, "Y": 0, "Z": 100 }
}

Constructors

ReferenceReturnSyntax()

Initializes a new instance with default settings (BareG28 = Alarm).

public ReferenceReturnSyntax()

ReferenceReturnSyntax(XElement)

Initializes a new instance by deserializing from the given XML element.

public ReferenceReturnSyntax(XElement src)

Parameters

src XElement

Source XML element.

Properties

BareG28

Behaviour for a G28 block with no axis specifiers. Defaults to Alarm.

public BareG28Behavior BareG28 { get; set; }

Property Value

BareG28Behavior

Name

Syntax kind name (typically the concrete type name).

public string Name { get; }

Property Value

string

XName

XML element name used to register this syntax with XFactory.

public static string XName { get; }

Property Value

string

Methods

Build(LazyLinkedListNode<SyntaxPiece>, List<INcDependency>, NcDiagnosticProgress)

Build syntax arrangement into the syntaxPieceNode in-place.

public void Build(LazyLinkedListNode<SyntaxPiece> syntaxPieceNode, List<INcDependency> ncDependencyList, NcDiagnosticProgress ncDiagnosticProgress)

Parameters

syntaxPieceNode LazyLinkedListNode<SyntaxPiece>
ncDependencyList List<INcDependency>
ncDiagnosticProgress NcDiagnosticProgress

MakeXmlSource(string, string, bool)

Creates an XML representation of the object. This method may also generate additional resources such as related files.

public XElement MakeXmlSource(string baseDirectory, string relFile, bool exhibitionOnly)

Parameters

baseDirectory string

The base directory for resolving relative paths

relFile string

The relative file path for the XML source

exhibitionOnly bool

if true, the extended file creation is suppressed.

Returns

XElement

An XML element representing the object's state

Remarks

For the demand of easy moving source folder (especially project folder) without configuration file path corruption, the relative file path is applied. The baseDirectory is typically the folder at the nearest configuration file folder. Since the folder can be moving with the configuration file.

Reg(XFactory)

Registers this type's deserializer with the given XFactory (or Default when factory is null). Idempotent.

public static void Reg(XFactory factory = null)

Parameters

factory XFactory