Enum BareG28Behavior
- 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 enum BareG28Behavior
- Extension Methods
Fields
Alarm = 0Emit
Coord-RefReturn–003validation error and consume the bare G28 without emitting motion.AllAxesHome = 1Interpret bare G28 as if every configured axis were listed at its current modal value, so item 0 (intermediate) is a no-op and item 1 sends each configured axis to its home. Requires an IMachineAxisConfig dep; without one the syntax falls back to Alarm.
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):
{ "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):
{ "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 }
}