fix: Cincinnati post processor arc feedrate, G89 spacing, pallet exchange, and preamble

- Add radius-based arc feedrate calculation (Variables/Percentages modes)
  with configurable radius ranges (#123/#124/#125 or inline expressions)
- Fix arc distance in SpeedClassifier using actual arc length instead of
  chord length (full circles previously computed as zero)
- Fix G89 P spacing: P now adjacent to filename per CL-707 manual syntax
- Add lead-out feedrate support (#129) and arc lead-in feedrate (#127)
- Fix pallet exchange: StartAndEnd emits M50 in preamble + last sheet only
- Add G121 Smart Rapids emission when UseSmartRapids is enabled
- Add G90 absolute mode to main program preamble alongside G20/G21

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-30 09:33:50 -04:00
parent 722f758e94
commit 3d4204db7b
10 changed files with 515 additions and 22 deletions
@@ -37,7 +37,8 @@ public sealed class CincinnatiSheetWriter
/// </param>
public void Write(TextWriter w, Plate plate, string nestName, int sheetIndex, int subNumber,
string cutLibrary, string etchLibrary,
Dictionary<(int, long), int> partSubprograms = null)
Dictionary<(int, long), int> partSubprograms = null,
bool isLastSheet = false)
{
if (plate.Parts.Count == 0)
return;
@@ -64,12 +65,12 @@ public sealed class CincinnatiSheetWriter
w.WriteLine("N10000");
w.WriteLine("G92 X#5021 Y#5022");
if (!string.IsNullOrEmpty(cutLibrary))
w.WriteLine($"G89 P {cutLibrary}");
w.WriteLine($"G89 P{cutLibrary}");
w.WriteLine($"M98 P{varDeclSub} (Variable Declaration)");
w.WriteLine("G90");
w.WriteLine("M47");
if (!string.IsNullOrEmpty(cutLibrary))
w.WriteLine($"G89 P {cutLibrary}");
w.WriteLine($"G89 P{cutLibrary}");
w.WriteLine("GOTO1( Goto Feature )");
// 3. Order parts: non-cutoff sorted by Bottom then Left, cutoffs last
@@ -94,7 +95,9 @@ public sealed class CincinnatiSheetWriter
// 5. Footer
w.WriteLine("M42");
w.WriteLine("G0 X0 Y0");
if (_config.PalletExchange != PalletMode.None)
var emitM50 = _config.PalletExchange == PalletMode.EndOfSheet
|| (_config.PalletExchange == PalletMode.StartAndEnd && isLastSheet);
if (emitM50)
w.WriteLine($"N{sheetIndex + 1} M50");
w.WriteLine($"M99 (END OF {nestName}.{sheetIndex:D3})");
}