CAM: snapmaker toolheads and spindle speeds
* Removed generic snapmaker machine and toolhead configuration. The idea of running a CNC code that is not matched to the machine's abilities and work area seems dangerous. * --machine argument is required * --toolhead argument is required when the selected machine is compatible with more than one toolhead. When the selected machine only supports one toolhead, it is selected as the default. * --spindle-percent defaults according to the selected toolhead capabilities. If the toolhead can do RPM, then RPM is used, otherwise falls back to percent. This option now functions as an override. * fixed a bug in convert_spindle() when RPM is selected. The gcode was not returned.
This commit is contained in:
@@ -76,7 +76,7 @@ class TestSnapmakerPost(PathTestUtils.PathTestBase):
|
||||
expected_header = """\
|
||||
;Header Start
|
||||
;header_type: cnc
|
||||
;machine: Snapmaker 2 A350
|
||||
;machine: Snapmaker 2 A350 50W CNC module
|
||||
;Post Processor: snapmaker_post
|
||||
;Cam File: boxtest.fcstd
|
||||
;Output Time: \\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{0,6}
|
||||
@@ -108,7 +108,7 @@ M5
|
||||
"""
|
||||
|
||||
# test header and body with comments
|
||||
gcode = self.get_gcode([], "--machine=A350 --toolhead=50W --spindle-percent")
|
||||
gcode = self.get_gcode([], "--machine=A350 --toolhead=50W_CNC")
|
||||
|
||||
g_lines = gcode.splitlines()
|
||||
e_lines = expected_header.splitlines() + expected_body.splitlines()
|
||||
@@ -121,12 +121,12 @@ M5
|
||||
self.assertEqual(exp, line)
|
||||
|
||||
# test body without header
|
||||
gcode = self.get_gcode([], "--machine=A350 --toolhead=50W --spindle-percent --no-header")
|
||||
gcode = self.get_gcode([], "--machine=A350 --toolhead=50W_CNC --no-header")
|
||||
self.assertEqual(gcode, expected_body)
|
||||
|
||||
# test body without comments
|
||||
gcode = self.get_gcode(
|
||||
[], "--machine=A350 --toolhead=50W --spindle-percent --no-header --no-comments"
|
||||
[], "--machine=A350 --toolhead=50W_CNC --no-header --no-comments"
|
||||
)
|
||||
expected = "".join(
|
||||
[line for line in expected_body.splitlines(keepends=True) if not line.startswith(";")]
|
||||
@@ -139,7 +139,7 @@ M5
|
||||
expected = "G0 X10.000 Y20.000 Z30.000"
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command], "--machine=A350 --toolhead=50W --spindle-percent --no-header"
|
||||
[command], "--machine=A350 --toolhead=50W_CNC --no-header"
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
@@ -151,7 +151,7 @@ M5
|
||||
expected = "G0 X10.00 Y20.00 Z30.00"
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command], "--machine=A350 --toolhead=50W --spindle-percent --no-header --precision=2"
|
||||
[command], "--machine=A350 --toolhead=50W_CNC --no-header --precision=2"
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
@@ -163,7 +163,7 @@ M5
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=A350 --toolhead=50W --spindle-percent --no-header --line-numbers --line-number=10 --line-increment=2",
|
||||
"--machine=A350 --toolhead=50W_CNC --no-header --line-numbers --line-number=10 --line-increment=2",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
@@ -172,7 +172,7 @@ M5
|
||||
"""Test Pre-amble"""
|
||||
gcode = self.get_gcode(
|
||||
[],
|
||||
"--machine=A350 --toolhead=50W --spindle-percent --no-header --preamble='G18 G55' --no-comments",
|
||||
"--machine=A350 --toolhead=50W_CNC --no-header --preamble='G18 G55' --no-comments",
|
||||
)
|
||||
result = gcode.splitlines()[0]
|
||||
self.assertEqual(result, "G18 G55")
|
||||
@@ -181,7 +181,7 @@ M5
|
||||
"""Test Post-amble"""
|
||||
gcode = self.get_gcode(
|
||||
[],
|
||||
"--machine=A350 --toolhead=50W --spindle-percent --no-header --postamble='G0 Z50\nM2' --no-comments",
|
||||
"--machine=A350 --toolhead=50W_CNC --no-header --postamble='G0 Z50\nM2' --no-comments",
|
||||
)
|
||||
result = gcode.splitlines()[-2]
|
||||
self.assertEqual(result, "G0 Z50")
|
||||
@@ -195,7 +195,7 @@ M5
|
||||
# test inches conversion
|
||||
expected = "G0 X0.3937 Y0.7874 Z1.1811"
|
||||
gcode = self.get_gcode(
|
||||
[command], "--machine=A350 --toolhead=50W --spindle-percent --no-header --inches"
|
||||
[command], "--machine=A350 --toolhead=50W_CNC --no-header --inches"
|
||||
)
|
||||
self.assertEqual(gcode.splitlines()[3], "G20")
|
||||
result = gcode.splitlines()[18]
|
||||
@@ -205,7 +205,7 @@ M5
|
||||
expected = "G0 X0.39 Y0.79 Z1.18"
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=A350 --toolhead=50W --spindle-percent --no-header --inches --precision=2",
|
||||
"--machine=A350 --toolhead=50W_CNC --no-header --inches --precision=2",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
@@ -218,7 +218,7 @@ M5
|
||||
expected = "G0 Y30.000"
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[c0, c1], "--machine=A350 --toolhead=50W --spindle-percent --no-header --axis-modal"
|
||||
[c0, c1], "--machine=A350 --toolhead=50W_CNC --no-header --axis-modal"
|
||||
)
|
||||
result = gcode.splitlines()[19]
|
||||
self.assertEqual(result, expected)
|
||||
@@ -230,7 +230,7 @@ M5
|
||||
c1 = Path.Command("M3 S3000")
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[c0, c1], "--machine=A350 --toolhead=50W --spindle-percent --no-header"
|
||||
[c0, c1], "--machine=A350 --toolhead=50W_CNC --no-header"
|
||||
)
|
||||
self.assertEqual(gcode.splitlines()[19:22], ["M5", "M76", "M6 T2"])
|
||||
self.assertEqual(
|
||||
@@ -256,88 +256,155 @@ M5
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=Original --toolhead=50W --spindle-percent --no-header",
|
||||
"--machine=Original --no-header",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=A150 --toolhead=50W --spindle-percent --no-header",
|
||||
"--machine=A150 --toolhead=50W_CNC --no-header",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=A250 --toolhead=50W --spindle-percent --no-header",
|
||||
"--machine=A250 --toolhead=50W_CNC --no-header",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=A250T --toolhead=50W --spindle-percent --no-header",
|
||||
"--machine=A250T --toolhead=50W_CNC --no-header",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=A250T --toolhead=200W --no-header",
|
||||
"--machine=A250T --toolhead=200W_CNC --no-header",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=A350 --toolhead=50W --spindle-percent --no-header",
|
||||
"--machine=A350 --toolhead=50W_CNC --no-header",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=A350T --toolhead=50W --spindle-percent --no-header",
|
||||
"--machine=A350T --toolhead=50W_CNC --no-header",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=A350T --toolhead=200W --no-header",
|
||||
"--machine=A350T --toolhead=200W_CNC --no-header",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=Artisan --toolhead=200W --no-header",
|
||||
"--machine=Artisan --no-header",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
def test_spindle(self):
|
||||
def test_toolhead_selection(self):
|
||||
"""Test automatic selection of toolhead where appropriate"""
|
||||
|
||||
# check succeeds
|
||||
command = Path.Command("G0 X10 Y20 Z30")
|
||||
expected = "G0 X10.000 Y20.000 Z30.000"
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=Original --no-header",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
self.assertEqual(self.post.values["TOOLHEAD_NAME"],"Original CNC module")
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=A350 --no-header",
|
||||
)
|
||||
self.assertFalse(isinstance(gcode,str))
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=A350T --no-header",
|
||||
)
|
||||
self.assertFalse(isinstance(gcode,str))
|
||||
|
||||
# check succeed with artisan (which base is bigger)
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=Artisan --no-header --boundaries-check",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
self.assertEqual(self.post.values["TOOLHEAD_NAME"],"200W CNC module")
|
||||
|
||||
def test_spindle_percent_rpm_auto_select(self):
|
||||
"""Test automatic selection of spindle speed rpm vs percent"""
|
||||
|
||||
command = Path.Command("M3 S2100")
|
||||
|
||||
# test original toolhead
|
||||
gcode = self.get_gcode(
|
||||
[command], "--machine=Original --no-header"
|
||||
)
|
||||
self.assertEqual(gcode.splitlines()[18], "M3 P30")
|
||||
|
||||
command = Path.Command("M3 S3600")
|
||||
|
||||
# test 50W toolhead
|
||||
gcode = self.get_gcode(
|
||||
[command], "--machine=A350 --toolhead=50W_CNC --no-header"
|
||||
)
|
||||
self.assertEqual(gcode.splitlines()[18], "M3 P30")
|
||||
|
||||
# test 200W toolhead
|
||||
gcode = self.get_gcode(
|
||||
[command], "--machine=A350 --toolhead=200W_CNC --no-header"
|
||||
)
|
||||
self.assertEqual(gcode.splitlines()[18], "M3 S3600")
|
||||
|
||||
# test 200W toolhead
|
||||
gcode = self.get_gcode(
|
||||
[command], "--machine=Artisan --no-header"
|
||||
)
|
||||
self.assertEqual(gcode.splitlines()[18], "M3 S3600")
|
||||
|
||||
def test_spindle_percent(self):
|
||||
"""Test spindle speed conversion from RPM to percents"""
|
||||
|
||||
command = Path.Command("M3 S3600")
|
||||
|
||||
# test 50W toolhead
|
||||
gcode = self.get_gcode(
|
||||
[command], "--machine=A350 --toolhead=50W --spindle-percent --no-header"
|
||||
[command], "--machine=A350 --toolhead=50W_CNC --spindle-percent --no-header"
|
||||
)
|
||||
self.assertEqual(gcode.splitlines()[18], "M3 P30")
|
||||
|
||||
# test 200W toolhead
|
||||
gcode = self.get_gcode(
|
||||
[command], "--machine=A350 --toolhead=200W --spindle-percent --no-header"
|
||||
[command], "--machine=A350 --toolhead=200W_CNC --spindle-percent --no-header"
|
||||
)
|
||||
self.assertEqual(gcode.splitlines()[18], "M3 P20")
|
||||
|
||||
# test custom spindle speed extrema
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=A350 --toolhead=200W --spindle-percent --no-header --spindle-speeds=3000,4000",
|
||||
"--machine=A350 --toolhead=200W_CNC --spindle-percent --no-header --spindle-speeds=3000,4000",
|
||||
)
|
||||
self.assertEqual(gcode.splitlines()[18], "M3 P90")
|
||||
|
||||
@@ -346,7 +413,7 @@ M5
|
||||
|
||||
command = Path.Command("(comment)")
|
||||
gcode = self.get_gcode(
|
||||
[command], "--machine=A350 --toolhead=50W --spindle-percent --no-header"
|
||||
[command], "--machine=A350 --toolhead=50W_CNC --spindle-percent --no-header"
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
expected = ";comment"
|
||||
@@ -360,7 +427,7 @@ M5
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=A350 --toolhead=50W --spindle-percent --no-header --boundaries-check",
|
||||
"--machine=A350 --toolhead=50W_CNC --no-header --boundaries-check",
|
||||
)
|
||||
self.assertTrue(self.post.check_boundaries(gcode.splitlines()))
|
||||
|
||||
@@ -369,20 +436,20 @@ M5
|
||||
c1 = Path.Command("G02 Y260")
|
||||
gcode = self.get_gcode(
|
||||
[c0, c1],
|
||||
"--machine=A350 --toolhead=50W --spindle-percent --no-header --boundaries-check",
|
||||
"--machine=A350 --toolhead=50W_CNC --no-header --boundaries-check",
|
||||
)
|
||||
self.assertFalse(self.post.check_boundaries(gcode.splitlines()))
|
||||
|
||||
# check succeed with artisan (which base is bigger)
|
||||
gcode = self.get_gcode(
|
||||
[c0, c1],
|
||||
"--machine=Artisan --toolhead=50W --spindle-percent --no-header --boundaries-check",
|
||||
"--machine=Artisan --no-header --boundaries-check",
|
||||
)
|
||||
self.assertTrue(self.post.check_boundaries(gcode.splitlines()))
|
||||
|
||||
# check fails with custom boundaries
|
||||
gcode = self.get_gcode(
|
||||
[c0, c1],
|
||||
"--machine=A350 --toolhead=50W --spindle-percent --no-header --boundaries-check --boundaries='50,400,10'",
|
||||
"--machine=A350 --toolhead=50W_CNC --no-header --boundaries-check --boundaries='50,400,10'",
|
||||
)
|
||||
self.assertFalse(self.post.check_boundaries(gcode.splitlines()))
|
||||
|
||||
@@ -51,47 +51,79 @@ SNAPMAKER_MACHINES = dict(
|
||||
key="Original",
|
||||
name="Snapmaker Original",
|
||||
boundaries=dict(X=90, Y=90, Z=50),
|
||||
compatible_toolheads={"Original_CNC"},
|
||||
),
|
||||
Original_Z_Extension=dict(
|
||||
key="Original_Z_Extension",
|
||||
name="Snapmaker Original with Z extension",
|
||||
boundaries=dict(X=90, Y=90, Z=146),
|
||||
compatible_toolheads={"Original_CNC"},
|
||||
),
|
||||
A150=dict(
|
||||
key="A150",
|
||||
name="Snapmaker 2 A150",
|
||||
boundaries=dict(X=160, Y=160, Z=90),
|
||||
compatible_toolheads={"50W_CNC"},
|
||||
),
|
||||
A250=dict(
|
||||
key="A250",
|
||||
name="Snapmaker 2 A250",
|
||||
boundaries=dict(X=230, Y=250, Z=180),
|
||||
compatible_toolheads={"50W_CNC", "200W_CNC"},
|
||||
),
|
||||
A250T=dict(
|
||||
key="A250T",
|
||||
name="Snapmaker 2 A250T",
|
||||
boundaries=dict(X=230, Y=250, Z=180),
|
||||
compatible_toolheads={"50W_CNC", "200W_CNC"},
|
||||
),
|
||||
A350=dict(
|
||||
key="A350",
|
||||
name="Snapmaker 2 A350",
|
||||
boundaries=dict(X=320, Y=350, Z=275),
|
||||
compatible_toolheads={"50W_CNC", "200W_CNC"},
|
||||
),
|
||||
A350T=dict(
|
||||
key="A350T",
|
||||
name="Snapmaker 2 A350T",
|
||||
boundaries=dict(X=320, Y=350, Z=275),
|
||||
compatible_toolheads={"50W_CNC", "200W_CNC"},
|
||||
),
|
||||
Artisan=dict(
|
||||
key="Artisan",
|
||||
name="Snapmaker Artisan",
|
||||
boundaries=dict(X=400, Y=400, Z=400),
|
||||
boundaries=dict(X=400, Y=413, Z=400),
|
||||
compatible_toolheads={"200W_CNC"},
|
||||
),
|
||||
)
|
||||
|
||||
# Could support other types of toolheads (laser, drag knife, 3DP, ...) in the future
|
||||
# https://wiki.snapmaker.com/en/Snapmaker_Luban/manual/2_supported_gcode_references#m3m4-modified-cnclaser-on
|
||||
SNAPMAKER_TOOLHEADS = {
|
||||
"50W": dict(name="50W CNC module", min=0, max=12000, percent=True),
|
||||
"200W": dict(name="200W CNC module", min=8000, max=18000, percent=False),
|
||||
"Original_CNC": dict(
|
||||
key="Original_CNC",
|
||||
name="Original CNC module",
|
||||
speed_rpm=dict(min=0, max=7000),
|
||||
boundaries_delta=dict(X=0, Y=0, Z=0),
|
||||
has_percent=True,
|
||||
has_speed_s=False,
|
||||
),
|
||||
"50W_CNC": dict(
|
||||
key="50W_CNC",
|
||||
name="50W CNC module",
|
||||
speed_rpm=dict(min=0, max=12000),
|
||||
boundaries_delta=dict(X=0, Y=0, Z=0),
|
||||
has_percent=True,
|
||||
has_speed_s=False,
|
||||
),
|
||||
"200W_CNC": dict(
|
||||
key="200W_CNC",
|
||||
name="200W CNC module",
|
||||
speed_rpm=dict(min=0, max=18000),
|
||||
boundaries_delta=dict(X=0, Y=-13, Z=0),
|
||||
has_percent=True,
|
||||
has_speed_s=True,
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
@@ -223,16 +255,9 @@ class Snapmaker(Path.Post.Processor.PostProcessor):
|
||||
self.values["BOUNDARIES_CHECK"] = False
|
||||
self.values["MACHINES"] = SNAPMAKER_MACHINES
|
||||
self.values["TOOLHEADS"] = SNAPMAKER_TOOLHEADS
|
||||
# default toolhead is 50W (the weakest one)
|
||||
self.values["DEFAULT_TOOLHEAD"] = "50W"
|
||||
self.values["TOOLHEAD_NAME"] = SNAPMAKER_TOOLHEADS[self.values["DEFAULT_TOOLHEAD"]]["name"]
|
||||
self.values["SPINDLE_SPEEDS"] = dict(
|
||||
min=SNAPMAKER_TOOLHEADS[self.values["DEFAULT_TOOLHEAD"]]["min"],
|
||||
max=SNAPMAKER_TOOLHEADS[self.values["DEFAULT_TOOLHEAD"]]["max"],
|
||||
)
|
||||
self.values["SPINDLE_PERCENT"] = SNAPMAKER_TOOLHEADS[self.values["DEFAULT_TOOLHEAD"]][
|
||||
"percent"
|
||||
]
|
||||
self.values["TOOLHEAD_NAME"] = None
|
||||
self.values["SPINDLE_SPEEDS"] = dict()
|
||||
self.values["SPINDLE_PERCENT"] = None
|
||||
|
||||
def snapmaker_init_argument_defaults(self) -> None:
|
||||
"""Initialize which arguments (in a pair) are shown as the default argument."""
|
||||
@@ -245,7 +270,6 @@ class Snapmaker(Path.Post.Processor.PostProcessor):
|
||||
self.argument_defaults["thumbnail"] = True
|
||||
self.argument_defaults["gui"] = True
|
||||
self.argument_defaults["boundaries-check"] = True
|
||||
self.argument_defaults["spindle-percent"] = True
|
||||
|
||||
def snapmaker_init_arguments_visible(self) -> None:
|
||||
"""Initialize which argument pairs are visible in TOOLTIP_ARGS."""
|
||||
@@ -349,14 +373,8 @@ class Snapmaker(Path.Post.Processor.PostProcessor):
|
||||
group.add_argument(
|
||||
"--spindle-percent",
|
||||
action="store_true",
|
||||
default=argument_defaults["spindle-percent"],
|
||||
help="use percent as toolhead spindle speed unit",
|
||||
)
|
||||
group.add_argument(
|
||||
"--spindle-rpm",
|
||||
action="store_false",
|
||||
dest="spindle_percent",
|
||||
help="Use RPM as toolhead spindle speed unit",
|
||||
default=None,
|
||||
help="use percent as toolhead spindle speed unit (default: use RPM if supported by toolhead, otherwise percent)",
|
||||
)
|
||||
|
||||
group.add_argument(
|
||||
@@ -390,33 +408,63 @@ class Snapmaker(Path.Post.Processor.PostProcessor):
|
||||
# The deepcopy is necessary to avoid modifying the boundaries in the MACHINES dict.
|
||||
self.values["BOUNDARIES"] = copy.deepcopy(machine["boundaries"])
|
||||
|
||||
if args.boundaries: # may override machine boundaries, which is expected
|
||||
self.values["BOUNDARIES"] = args.boundaries
|
||||
|
||||
if args.toolhead:
|
||||
if args.toolhead not in machine["compatible_toolheads"]:
|
||||
FreeCAD.Console.PrintError(
|
||||
f"Selected --toolhead={args.toolhead} is not compatible with machine {machine['name']}."
|
||||
+f" Choose from [{machine['compatible_toolheads']}]\n")
|
||||
flag = False
|
||||
return (flag, args)
|
||||
toolhead = self.values["TOOLHEADS"][args.toolhead]
|
||||
self.values["TOOLHEAD_NAME"] = toolhead["name"]
|
||||
elif len(machine["compatible_toolheads"]) == 1:
|
||||
toolhead_key = next(iter(machine["compatible_toolheads"]))
|
||||
toolhead = self.values["TOOLHEADS"][toolhead_key]
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
f'No toolhead selected, using default ({self.values["TOOLHEAD_NAME"]}). '
|
||||
f"Consider adding --toolhead\n"
|
||||
FreeCAD.Console.PrintError(
|
||||
f"Machine {machine['name']} has multiple compatible toolheads:\n"
|
||||
f"{machine['compatible_toolheads']}\n"
|
||||
"Please add --toolhead argument.\n"
|
||||
)
|
||||
toolhead = self.values["TOOLHEADS"][self.values["DEFAULT_TOOLHEAD"]]
|
||||
flag = False
|
||||
return (flag, args)
|
||||
self.values["TOOLHEAD_KEY"] = toolhead["key"]
|
||||
self.values["TOOLHEAD_NAME"] = toolhead["name"]
|
||||
|
||||
self.values["SPINDLE_SPEEDS"] = {key: toolhead[key] for key in ("min", "max")}
|
||||
self.values["SPINDLE_SPEEDS"] = toolhead["speed_rpm"]
|
||||
|
||||
if args.spindle_speeds: # may override toolhead value, which is expected
|
||||
self.values["SPINDLE_SPEEDS"] = args.spindle_speeds
|
||||
|
||||
if args.spindle_percent is not None:
|
||||
if toolhead["percent"] is True:
|
||||
if toolhead["has_percent"]:
|
||||
self.values["SPINDLE_PERCENT"] = True
|
||||
if args.spindle_percent is False:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Toolhead does not handle RPM spindle speed, using percents instead.\n"
|
||||
)
|
||||
else:
|
||||
self.values["SPINDLE_PERCENT"] = args.spindle_percent
|
||||
FreeCAD.Console.PrintError(
|
||||
f"Requested spindle speed in percent, but toolhead {toolhead['name']}"
|
||||
+" does not support speed as percent.\n"
|
||||
)
|
||||
flag = False
|
||||
return (flag, args)
|
||||
else:
|
||||
# Prefer speed S over percent P
|
||||
self.values["SPINDLE_PERCENT"] = toolhead['has_percent'] and not toolhead['has_speed_s']
|
||||
if self.values["SPINDLE_PERCENT"]:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Spindle speed will be controlled using using percentages.\n"
|
||||
)
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Spindle speed will be controlled using using RPM.\n"
|
||||
)
|
||||
|
||||
if args.boundaries: # may override machine boundaries, which is expected
|
||||
self.values["BOUNDARIES"] = args.boundaries
|
||||
self.values["MACHINE_NAME"] += " Boundaries overide=" + str(args.boundaries)
|
||||
else:
|
||||
# Update machine dimensions based on installed toolhead
|
||||
for axis in toolhead["boundaries_delta"].keys():
|
||||
self.values["BOUNDARIES"][axis] += toolhead["boundaries_delta"][axis]
|
||||
self.values["MACHINE_NAME"] += " " + toolhead["name"]
|
||||
|
||||
self.values["THUMBNAIL"] = args.thumbnail
|
||||
self.values["ALLOW_GUI"] = args.gui
|
||||
@@ -539,9 +587,10 @@ class Snapmaker(Path.Post.Processor.PostProcessor):
|
||||
def convert_spindle(self, gcode: List[str]) -> List[str]:
|
||||
"""convert spindle speed values from RPM to percent (%) (M3/M4 commands)"""
|
||||
if self.values["SPINDLE_PERCENT"] is False:
|
||||
return
|
||||
return gcode
|
||||
|
||||
# TODO: check if percentage covers range 0-max (most probable) or min-max (200W has a documented min speed)
|
||||
# https://wiki.snapmaker.com/en/Snapmaker_Luban/manual/2_supported_gcode_references#m3m4-modified-cnclaser-on
|
||||
# Speed as percentage in [0,100]% range
|
||||
for index, commandline in enumerate(
|
||||
gcode
|
||||
): # .split(self.values["END_OF_LINE_CHARACTERS"]):
|
||||
|
||||
Reference in New Issue
Block a user