CAM: snapmaker add --quick-swap and --bracing-kit options
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
# * implied. See the Licence for the specific language governing *
|
||||
# * permissions and limitations under the Licence. *
|
||||
# ***************************************************************************
|
||||
import argparse
|
||||
import re
|
||||
from typing import List
|
||||
|
||||
@@ -317,6 +318,129 @@ M5
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
def test_mod_kits(self):
|
||||
"""Test the various mod kits against various models."""
|
||||
|
||||
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["MOD_KITS_INSTALLED"],[])
|
||||
self.assertEqual(self.post.values["BOUNDARIES"],dict(X=90, Y=90, Z=50))
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=Original --quick-swap --no-header",
|
||||
)
|
||||
# I don't understand why export returns the arguments
|
||||
# if snapmaker_process_arguments fails.
|
||||
self.assertTrue(isinstance(gcode,argparse.Namespace))
|
||||
self.assertFalse(isinstance(gcode,str))
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=Original --bracing-kit --no-header",
|
||||
)
|
||||
# I don't understand why export returns the arguments
|
||||
# if snapmaker_process_arguments fails.
|
||||
self.assertTrue(isinstance(gcode,argparse.Namespace))
|
||||
self.assertFalse(isinstance(gcode,str))
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=Artisan --no-header",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
self.assertEqual(self.post.values["MOD_KITS_INSTALLED"],[])
|
||||
self.assertEqual(self.post.values["BOUNDARIES"],dict(X=400, Y=400, Z=400))
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=Artisan --quick-swap --no-header",
|
||||
)
|
||||
# I don't understand why export returns the arguments
|
||||
# if snapmaker_process_arguments fails.
|
||||
self.assertTrue(isinstance(gcode,argparse.Namespace))
|
||||
self.assertFalse(isinstance(gcode,str))
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=Artisan --bracing-kit --no-header",
|
||||
)
|
||||
# I don't understand why export returns the arguments
|
||||
# if snapmaker_process_arguments fails.
|
||||
self.assertTrue(isinstance(gcode,argparse.Namespace))
|
||||
self.assertFalse(isinstance(gcode,str))
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=A150 --toolhead=50W_CNC --bracing-kit --no-header",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
self.assertEqual(self.post.values["MOD_KITS_INSTALLED"],["BK"])
|
||||
self.assertEqual(self.post.values["BOUNDARIES"],dict(X=160, Y=148, Z=84))
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=A150 --toolhead=50W_CNC --quick-swap --no-header",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
self.assertEqual(self.post.values["MOD_KITS_INSTALLED"],["QS"])
|
||||
self.assertEqual(self.post.values["BOUNDARIES"],dict(X=160, Y=145, Z=75))
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=A250 --toolhead=50W_CNC --bracing-kit --quick-swap --no-header",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
self.assertEqual(self.post.values["MOD_KITS_INSTALLED"],["QS","BK"])
|
||||
self.assertEqual(self.post.values["BOUNDARIES"],dict(X=230, Y=223, Z=159))
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=A250T --toolhead=50W_CNC --quick-swap --no-header",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
self.assertEqual(self.post.values["MOD_KITS_INSTALLED"],["QS"])
|
||||
self.assertEqual(self.post.values["BOUNDARIES"],dict(X=230, Y=235, Z=165))
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=A350 --toolhead=50W_CNC --bracing-kit --quick-swap --no-header",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
self.assertEqual(self.post.values["MOD_KITS_INSTALLED"],["QS","BK"])
|
||||
self.assertEqual(self.post.values["BOUNDARIES"],dict(X=320, Y=323, Z=254))
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=A350T --toolhead=50W_CNC --bracing-kit --quick-swap --no-header",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
self.assertEqual(self.post.values["MOD_KITS_INSTALLED"],["QS","BK"])
|
||||
self.assertEqual(self.post.values["BOUNDARIES"],dict(X=320, Y=323, Z=254))
|
||||
|
||||
gcode = self.get_gcode(
|
||||
[command],
|
||||
"--machine=A350T --toolhead=200W_CNC --bracing-kit --quick-swap --no-header",
|
||||
)
|
||||
result = gcode.splitlines()[18]
|
||||
self.assertEqual(result, expected)
|
||||
self.assertEqual(self.post.values["MOD_KITS_INSTALLED"],["QS","BK"])
|
||||
self.assertEqual(self.post.values["BOUNDARIES"],dict(X=320, Y=310, Z=254))
|
||||
|
||||
def test_toolhead_selection(self):
|
||||
"""Test automatic selection of toolhead where appropriate"""
|
||||
|
||||
|
||||
@@ -46,6 +46,15 @@ if DEBUG := False:
|
||||
else:
|
||||
Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule())
|
||||
|
||||
def convert_option_to_attr(option_name):
|
||||
# transforms argparse options into identifiers
|
||||
if option_name.startswith('--'):
|
||||
option_name = option_name[2:]
|
||||
elif option_name.startswith('-'):
|
||||
option_name = option_name[1:]
|
||||
|
||||
return option_name.replace('-','_')
|
||||
|
||||
SNAPMAKER_MACHINES = dict(
|
||||
Original=dict(
|
||||
key="Original",
|
||||
@@ -105,6 +114,27 @@ SNAPMAKER_MACHINES = dict(
|
||||
),
|
||||
)
|
||||
|
||||
# These modifications were released to upgrade the Snapmaker 2.0 machines
|
||||
# which started on Kickstarter.
|
||||
SNAPMAKER_MOD_KITS = {
|
||||
"QS": dict(
|
||||
key="QS",
|
||||
name="Quick Swap Kit",
|
||||
option_name="--quick-swap",
|
||||
option_help_text="Indicates that the quick swap kit is installed. Only compatible with Snapmaker 2 machines.",
|
||||
compatible_machines={"A150","A250","A250T","A350","A350T"},
|
||||
boundaries_delta=dict(X=0, Y=-15, Z=-15),
|
||||
),
|
||||
"BK": dict(
|
||||
key="BK",
|
||||
name="Bracing Kit",
|
||||
option_name="--bracing-kit",
|
||||
option_help_text="Indicates that the bracing kit is installed. Only compatible with Snapmaker 2 machines.",
|
||||
compatible_machines={"A150","A250","A250T","A350","A350T"},
|
||||
boundaries_delta=dict(X=0, Y=-12, Z=-6),
|
||||
),
|
||||
}
|
||||
|
||||
# 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 = {
|
||||
@@ -262,6 +292,7 @@ class Snapmaker(Path.Post.Processor.PostProcessor):
|
||||
self.values["BOUNDARIES"] = None
|
||||
self.values["BOUNDARIES_CHECK"] = False
|
||||
self.values["MACHINES"] = SNAPMAKER_MACHINES
|
||||
self.values["MOD_KITS_ALL"] = SNAPMAKER_MOD_KITS
|
||||
self.values["TOOLHEADS"] = SNAPMAKER_TOOLHEADS
|
||||
self.values["TOOLHEAD_NAME"] = None
|
||||
self.values["SPINDLE_SPEEDS"] = dict()
|
||||
@@ -353,7 +384,7 @@ class Snapmaker(Path.Post.Processor.PostProcessor):
|
||||
"--boundaries",
|
||||
action=CoordinatesAction,
|
||||
default=None,
|
||||
help='Custom boundaries (e.g. "100, 200, 300"). Overrides --machine',
|
||||
help='Custom boundaries (e.g. "100, 200, 300"). Overrides boundaries from --machine',
|
||||
)
|
||||
|
||||
group.add_argument(
|
||||
@@ -364,6 +395,14 @@ class Snapmaker(Path.Post.Processor.PostProcessor):
|
||||
help=f"Snapmaker machine. Choose from [{self.values['MACHINES'].keys()}].",
|
||||
)
|
||||
|
||||
for key, value in SNAPMAKER_MOD_KITS.items():
|
||||
group.add_argument(
|
||||
value["option_name"],
|
||||
default=False,
|
||||
action="store_true",
|
||||
help=value["option_help_text"],
|
||||
)
|
||||
|
||||
group.add_argument(
|
||||
"--toolhead",
|
||||
default=None,
|
||||
@@ -465,10 +504,25 @@ class Snapmaker(Path.Post.Processor.PostProcessor):
|
||||
"Spindle speed will be controlled using using RPM.\n"
|
||||
)
|
||||
|
||||
self.values["MOD_KITS_INSTALLED"] = []
|
||||
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 kits
|
||||
for mod_kit in self.values["MOD_KITS_ALL"].values():
|
||||
if getattr(args, convert_option_to_attr(mod_kit["option_name"])):
|
||||
if self.values["MACHINE_KEY"] not in mod_kit["compatible_machines"]:
|
||||
FreeCAD.Console.PrintError(
|
||||
f"Machine {machine['name']} is not compatible with {mod_kit["option_name"]}.\n"
|
||||
)
|
||||
flag = False
|
||||
return (flag, args)
|
||||
self.values["MACHINE_NAME"] += " " + mod_kit["name"]
|
||||
self.values["MOD_KITS_INSTALLED"].append(mod_kit["key"])
|
||||
for axis in mod_kit["boundaries_delta"].keys():
|
||||
self.values["BOUNDARIES"][axis] += mod_kit["boundaries_delta"][axis]
|
||||
|
||||
# Update machine dimensions based on installed toolhead
|
||||
for axis in toolhead["boundaries_delta"].keys():
|
||||
self.values["BOUNDARIES"][axis] += toolhead["boundaries_delta"][axis]
|
||||
|
||||
Reference in New Issue
Block a user