From d00d1b53e54c2c2f23233098884145b58fca1a85 Mon Sep 17 00:00:00 2001 From: Joacim Breiler Date: Sun, 9 Jun 2024 21:28:45 +0200 Subject: [PATCH] Reads the max spindle speed from the controller and automatically updates the designer job (#2543) --- .../firmware/DefaultFirmwareSettings.java | 5 + .../firmware/IFirmwareSettings.java | 11 ++- .../firmware/fluidnc/FluidNCSettings.java | 47 +++++++++- .../firmware/fluidnc/SpeedMap.java | 49 ++++++++++ .../commands/GetFirmwareSettingsCommand.java | 4 +- .../firmware/grbl/GrblFirmwareSettings.java | 9 ++ .../firmware/tinyg/TinyGFirmwareSettings.java | 5 + .../firmware/fluidnc/SpeedMapTest.java | 31 ++++++ .../nbp/designer/entities/EntitySetting.java | 2 + .../nbp/designer/gui/ToolSettingsPanel.java | 38 ++++---- .../SelectionSettingsModel.java | 26 ++++- .../designer/io/gcode/SimpleGcodeRouter.java | 26 +++-- .../nbp/designer/io/gcode/path/GcodePath.java | 4 + .../nbp/designer/io/gcode/path/Segment.java | 20 +++- .../io/gcode/toolpaths/AbstractToolPath.java | 12 ++- .../io/gcode/toolpaths/LaserFillToolPath.java | 2 +- .../gcode/toolpaths/LaserOutlineToolPath.java | 2 +- .../io/gcode/toolpaths/OutlineToolPath.java | 2 +- .../io/gcode/toolpaths/PocketToolPath.java | 2 +- .../ugs/nbp/designer/model/Settings.java | 26 ++--- .../platform/DesignerTopComponent.java | 29 +++++- .../designer/platform/SettingsAdapter.java | 6 +- .../gcode/toolpaths/LaserOutlinePathTest.java | 85 ++++++++++++++++- .../gcode/toolpaths/OutlineToolPathTest.java | 94 +++++++++++++++++++ 24 files changed, 464 insertions(+), 73 deletions(-) create mode 100644 ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/SpeedMap.java create mode 100644 ugs-core/test/com/willwinder/universalgcodesender/firmware/fluidnc/SpeedMapTest.java diff --git a/ugs-core/src/com/willwinder/universalgcodesender/firmware/DefaultFirmwareSettings.java b/ugs-core/src/com/willwinder/universalgcodesender/firmware/DefaultFirmwareSettings.java index 3d6949c5d4..333757a4b2 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/firmware/DefaultFirmwareSettings.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/DefaultFirmwareSettings.java @@ -144,6 +144,11 @@ public double getMaximumRate(Axis axis) { return 0; } + @Override + public int getMaxSpindleSpeed() throws FirmwareSettingsException { + return 0; + } + @Override public UnitUtils.Units getReportingUnits() { return UnitUtils.Units.UNKNOWN; diff --git a/ugs-core/src/com/willwinder/universalgcodesender/firmware/IFirmwareSettings.java b/ugs-core/src/com/willwinder/universalgcodesender/firmware/IFirmwareSettings.java index 0397507a2a..0bce0896e9 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/firmware/IFirmwareSettings.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/IFirmwareSettings.java @@ -142,7 +142,7 @@ public interface IFirmwareSettings { /** * Sets the number of steps needed to move the machine one millimeter. * - * @param axis the axis to retrieve the setting for + * @param axis the axis to retrieve the setting for * @param stepsPerMillimeter the number of steps to move one millimeter * @throws FirmwareSettingsException if the settings couldn't be saved */ @@ -185,7 +185,7 @@ public interface IFirmwareSettings { /** * Sets if the homing direction should be inverted for the given axis * - * @param axis the axis to make the setting for + * @param axis the axis to make the setting for * @param inverted set to true if homing should be performed in a negative direction */ void setHomingDirectionInverted(Axis axis, boolean inverted) throws FirmwareSettingsException; @@ -218,4 +218,11 @@ public interface IFirmwareSettings { * @return the maximum rate in mm/min */ double getMaximumRate(Axis axis) throws FirmwareSettingsException; + + /** + * Returns the controller max spindle speed + * + * @return the max spindle speed + */ + int getMaxSpindleSpeed() throws FirmwareSettingsException; } diff --git a/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/FluidNCSettings.java b/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/FluidNCSettings.java index 8a126ff22d..ae25969700 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/FluidNCSettings.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/FluidNCSettings.java @@ -1,3 +1,21 @@ +/* + Copyright 2022-2024 Will Winder + + This file is part of Universal Gcode Sender (UGS). + + UGS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + UGS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with UGS. If not, see . + */ package com.willwinder.universalgcodesender.firmware.fluidnc; import com.willwinder.universalgcodesender.IController; @@ -23,7 +41,11 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Logger; +import java.util.stream.Stream; +/** + * @author Joacim Breiler + */ public class FluidNCSettings implements IFirmwareSettings { private static final Logger LOGGER = Logger.getLogger(FluidNCSettings.class.getName()); @@ -44,7 +66,7 @@ public void refresh() throws FirmwareSettingsException { firmwareSettingsCommand.getSettings().keySet().forEach(key -> { String value = firmwareSettingsCommand.getSettings().get(key); FirmwareSetting firmwareSetting = new FirmwareSetting(key, value, "", "", ""); - settings.put(key, firmwareSetting); + settings.put(key.toLowerCase(), firmwareSetting); listeners.forEach(l -> l.onUpdatedFirmwareSetting(firmwareSetting)); }); } @@ -61,6 +83,7 @@ public Optional getSetting(String key) { @Override public FirmwareSetting setValue(String key, String value) throws FirmwareSettingsException { try { + key = key.toLowerCase(); if (!settings.containsKey(key) || !settings.get(key).getValue().equals(value)) { FluidNCCommand systemCommand = new FluidNCCommand("$/" + key + "=" + value); ControllerUtils.sendAndWaitForCompletion(controller, systemCommand); @@ -200,7 +223,7 @@ public void setHardLimitsInverted(boolean inverted) throws FirmwareSettingsExcep public void setSettings(List settings) throws FirmwareSettingsException { settings.forEach(setting -> { try { - setValue(setting.getKey(), setting.getValue()); + setValue(setting.getKey().toLowerCase(), setting.getValue()); } catch (FirmwareSettingsException e) { LOGGER.warning("Couldn't set the firmware setting " + setting.getKey() + " to value " + setting.getValue() + ". Error message: " + e.getMessage()); } @@ -211,4 +234,24 @@ public void setSettings(List settings) throws FirmwareSettingsE public double getMaximumRate(Axis axis) throws FirmwareSettingsException { return 0; } + + private Optional getSpeedMap(String speedMapSetting) { + FirmwareSetting value = settings.get(speedMapSetting); + return Optional.ofNullable(value) + .map(FirmwareSetting::getValue) + .map(SpeedMap::new); + } + + @Override + public int getMaxSpindleSpeed() throws FirmwareSettingsException { + return Stream.of(getSpeedMap("laser/speed_map"), + getSpeedMap("10V/speed_map"), + getSpeedMap("pwm/speed_map"), + getSpeedMap("besc/speed_map")) + .filter(Optional::isPresent) + .map(Optional::get) + .map(SpeedMap::getMax) + .findFirst() + .orElseThrow(() -> new FirmwareSettingsException("Could not find setting for max speed")); + } } diff --git a/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/SpeedMap.java b/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/SpeedMap.java new file mode 100644 index 0000000000..3e55b40d5f --- /dev/null +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/SpeedMap.java @@ -0,0 +1,49 @@ +/* + Copyright 2024 Will Winder + + This file is part of Universal Gcode Sender (UGS). + + UGS is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + UGS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with UGS. If not, see . + */ +package com.willwinder.universalgcodesender.firmware.fluidnc; + +import java.util.HashMap; +import java.util.Map; + +/** + * A class for parsing FluidNC speed maps + * + * @author Joacim Breiler + */ +public class SpeedMap { + private final Map speeds = new HashMap<>(); + + public SpeedMap(String speedMaps) { + String[] speeds = speedMaps.split(" "); + for (String speedMap : speeds) { + String[] split = speedMap.split("="); + if (split.length != 2) { + continue; + } + + this.speeds.put(Integer.parseInt(split[0].trim()), Double.parseDouble(split[1].trim().replace("%", ""))); + } + } + + public int getMax() { + return speeds.keySet().stream() + .max((s1, s2) -> speeds.get(s1).compareTo(speeds.get(s2))) + .orElse(0); + } +} diff --git a/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/commands/GetFirmwareSettingsCommand.java b/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/commands/GetFirmwareSettingsCommand.java index 5bb7360d93..3c6f6eb351 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/commands/GetFirmwareSettingsCommand.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/commands/GetFirmwareSettingsCommand.java @@ -51,7 +51,7 @@ private Map flatten(Map mapToFlatten) { .filter(Objects::nonNull) .flatMap(this::flatten) .collect(LinkedHashMap::new, (map, entry) -> - map.put(entry.getKey(), entry.getValue().toString()), LinkedHashMap::putAll); + map.put(entry.getKey().toLowerCase(), entry.getValue().toString()), LinkedHashMap::putAll); } private Stream> flatten(Map.Entry entry) { @@ -63,7 +63,7 @@ private Stream> flatten(Map.Entry entr if (value instanceof Map) { Map properties = (Map) value; return properties.entrySet().stream() - .flatMap(e -> flatten(new AbstractMap.SimpleEntry<>(entry.getKey() + "/" + e.getKey(), e.getValue()))); + .flatMap(e -> flatten(new AbstractMap.SimpleEntry<>(entry.getKey().toLowerCase() + "/" + e.getKey().toString().toLowerCase(), e.getValue()))); } return Stream.of(entry); diff --git a/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblFirmwareSettings.java b/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblFirmwareSettings.java index a01e13a298..8f8fb0d9cf 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblFirmwareSettings.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblFirmwareSettings.java @@ -59,6 +59,7 @@ public class GrblFirmwareSettings implements ICommunicatorListener, IFirmwareSet private static final String KEY_HARD_LIMITS_ENABLED = "$21"; private static final String KEY_HOMING_ENABLED = "$22"; private static final String KEY_HOMING_INVERT_DIRECTION = "$23"; + private static final String KEY_MAX_SPINDLE_SPEED = "$30"; private static final String KEY_INVERT_DIRECTION = "$3"; private static final String KEY_INVERT_LIMIT_PINS = "$5"; private static final String KEY_STEPS_PER_MM_X = "$100"; @@ -370,6 +371,14 @@ public double getMaximumRate(Axis axis) throws FirmwareSettingsException { } } + @Override + public int getMaxSpindleSpeed() throws FirmwareSettingsException { + return getSetting(KEY_MAX_SPINDLE_SPEED) + .map(FirmwareSetting::getValue) + .map(Integer::valueOf) + .orElse(0); + } + private int getInvertDirectionMask() { return getSetting(KEY_INVERT_DIRECTION) .map(FirmwareSetting::getValue) diff --git a/ugs-core/src/com/willwinder/universalgcodesender/firmware/tinyg/TinyGFirmwareSettings.java b/ugs-core/src/com/willwinder/universalgcodesender/firmware/tinyg/TinyGFirmwareSettings.java index b579f7f878..925778bf81 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/firmware/tinyg/TinyGFirmwareSettings.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/tinyg/TinyGFirmwareSettings.java @@ -191,6 +191,11 @@ public double getMaximumRate(Axis axis) throws FirmwareSettingsException { return 0; } + @Override + public int getMaxSpindleSpeed() throws FirmwareSettingsException { + throw new FirmwareSettingsException("Not implemented"); + } + /* * IFirmwareSettingsListener */ diff --git a/ugs-core/test/com/willwinder/universalgcodesender/firmware/fluidnc/SpeedMapTest.java b/ugs-core/test/com/willwinder/universalgcodesender/firmware/fluidnc/SpeedMapTest.java new file mode 100644 index 0000000000..a3af74713d --- /dev/null +++ b/ugs-core/test/com/willwinder/universalgcodesender/firmware/fluidnc/SpeedMapTest.java @@ -0,0 +1,31 @@ +package com.willwinder.universalgcodesender.firmware.fluidnc; + +import static org.junit.Assert.*; +import org.junit.Test; + +public class SpeedMapTest { + + @Test + public void getMaxShouldReturnTheHundredPercentMaxSpindleSpeed() { + SpeedMap speedMap = new SpeedMap("0=0.00% 0=0.00% 5000=100.00%"); + assertEquals(5000, speedMap.getMax()); + } + + @Test + public void getMaxShouldReturnTheMaxSpindleSpeedRegardlessOfOrder() { + SpeedMap speedMap = new SpeedMap("5000=100.00% 0=0.00% "); + assertEquals(5000, speedMap.getMax()); + } + + @Test + public void getMaxShouldReturnValueOfTheHighestPercent() { + SpeedMap speedMap = new SpeedMap("5000=99.00% 0=0.00% 4000=100%"); + assertEquals(4000, speedMap.getMax()); + } + + @Test + public void speedMapShouldHandleExtraSpacing() { + SpeedMap speedMap = new SpeedMap("0=0.00% 5000=50.00% 10000=100.00%"); + assertEquals(10000, speedMap.getMax()); + } +} \ No newline at end of file diff --git a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/entities/EntitySetting.java b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/entities/EntitySetting.java index 1bd5ec1c2c..5c8b5a1eef 100644 --- a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/entities/EntitySetting.java +++ b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/entities/EntitySetting.java @@ -55,6 +55,8 @@ public enum EntitySetting { EntitySetting.ROTATION, EntitySetting.START_DEPTH, EntitySetting.TARGET_DEPTH, + EntitySetting.SPINDLE_SPEED, + EntitySetting.FEED_RATE, EntitySetting.TEXT); public static final List DEFAULT_LASER_SETTINGS = List.of( diff --git a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/gui/ToolSettingsPanel.java b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/gui/ToolSettingsPanel.java index b5760ba4a6..d32252b534 100644 --- a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/gui/ToolSettingsPanel.java +++ b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/gui/ToolSettingsPanel.java @@ -25,6 +25,7 @@ This file is part of Universal Gcode Sender (UGS). import com.willwinder.universalgcodesender.uielements.TextFieldWithUnit; import net.miginfocom.swing.MigLayout; +import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSeparator; @@ -45,7 +46,7 @@ public class ToolSettingsPanel extends JPanel { private JTextField depthPerPass; private JTextField stepOver; private JTextField safeHeight; - private JTextField spindleSpeed; + private JCheckBox detectMaxSpindleSpeed; private TextFieldWithUnit laserDiameter; private TextFieldWithUnit maxSpindleSpeed; @@ -63,7 +64,14 @@ private void initComponents() { toolDiameter = new TextFieldWithUnit(TextFieldUnit.MM, 3, controller.getSettings().getToolDiameter()); add(toolDiameter, TOOL_FIELD_CONSTRAINT); - add(new JLabel("Feed speed" )); + add(new JLabel("Tool step over" )); + stepOver = new TextFieldWithUnit(TextFieldUnit.PERCENT, 2, + controller.getSettings().getToolStepOver()); + add(stepOver, TOOL_FIELD_CONSTRAINT); + + add(new JSeparator(SwingConstants.HORIZONTAL), "spanx, grow, wrap, hmin 2" ); + + add(new JLabel("Default feed speed" )); feedSpeed = new TextFieldWithUnit(TextFieldUnit.MM_PER_MINUTE, 0, controller.getSettings().getFeedSpeed()); add(feedSpeed, TOOL_FIELD_CONSTRAINT); @@ -75,19 +83,15 @@ private void initComponents() { depthPerPass = new TextFieldWithUnit(TextFieldUnit.MM, 2, controller.getSettings().getDepthPerPass()); add(depthPerPass, TOOL_FIELD_CONSTRAINT); - add(new JLabel("Step over" )); - stepOver = new TextFieldWithUnit(TextFieldUnit.PERCENT, 2, - controller.getSettings().getToolStepOver()); - add(stepOver, TOOL_FIELD_CONSTRAINT); - add(new JLabel("Safe height" )); safeHeight = new TextFieldWithUnit(TextFieldUnit.MM, 2, controller.getSettings().getSafeHeight()); add(safeHeight, TOOL_FIELD_CONSTRAINT); add(new JSeparator(SwingConstants.HORIZONTAL), "spanx, grow, wrap, hmin 2" ); - add(new JLabel("Spindle speed" )); - spindleSpeed = new TextFieldWithUnit(TextFieldUnit.ROTATIONS_PER_MINUTE, 0, controller.getSettings().getSpindleSpeed()); - add(spindleSpeed, TOOL_FIELD_CONSTRAINT); + + add(new JLabel("Detect max spindle speed" )); + detectMaxSpindleSpeed = new JCheckBox("", controller.getSettings().getDetectMaxSpindleSpeed()); + add(detectMaxSpindleSpeed, TOOL_FIELD_CONSTRAINT); add(new JLabel("Max spindle speed" )); maxSpindleSpeed = new TextFieldWithUnit(TextFieldUnit.ROTATIONS_PER_MINUTE, 0, controller.getSettings().getMaxSpindleSpeed()); @@ -148,14 +152,6 @@ public double getSafeHeight() { } } - public double getSpindleSpeed() { - try { - return Utils.formatter.parse(spindleSpeed.getText()).doubleValue(); - } catch (ParseException e) { - return controller.getSettings().getSpindleSpeed(); - } - } - private double getLaserDiameter() { try { return Utils.formatter.parse(laserDiameter.getText()).doubleValue(); @@ -172,6 +168,10 @@ private double getMaxSpindleSpeed() { } } + private boolean getDetectMaxSpindleSpeed() { + return detectMaxSpindleSpeed.isSelected(); + } + public Settings getSettings() { Settings settings = new Settings(); settings.applySettings(controller.getSettings()); @@ -181,9 +181,9 @@ public Settings getSettings() { settings.setToolDiameter(getToolDiameter()); settings.setToolStepOver(getStepOver()); settings.setPlungeSpeed(getPlungeSpeed()); - settings.setSpindleSpeed(getSpindleSpeed()); settings.setLaserDiameter(getLaserDiameter()); settings.setMaxSpindleSpeed((int) getMaxSpindleSpeed()); + settings.setDetectMaxSpindleSpeed(getDetectMaxSpindleSpeed()); return settings; } } diff --git a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/gui/selectionsettings/SelectionSettingsModel.java b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/gui/selectionsettings/SelectionSettingsModel.java index edcbbf2749..b700b8a69b 100644 --- a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/gui/selectionsettings/SelectionSettingsModel.java +++ b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/gui/selectionsettings/SelectionSettingsModel.java @@ -24,6 +24,8 @@ This file is part of Universal Gcode Sender (UGS). import com.willwinder.ugs.nbp.designer.entities.cuttable.CutType; import com.willwinder.ugs.nbp.designer.entities.cuttable.Group; import com.willwinder.ugs.nbp.designer.entities.cuttable.Text; +import com.willwinder.ugs.nbp.designer.logic.Controller; +import com.willwinder.ugs.nbp.designer.logic.ControllerFactory; import java.awt.Font; import java.io.Serializable; @@ -133,6 +135,7 @@ public void reset() { setStartDepth(0); setTargetDepth(0); setSpindleSpeed(0); + setFeedRate(0); setText(""); setFontFamily(Font.SANS_SERIF); } @@ -182,11 +185,14 @@ public void setStartDepth(double startDepth) { } public int getSpindleSpeed() { - return (Integer) settings.getOrDefault(EntitySetting.SPINDLE_SPEED, 0); + return (Integer) settings.getOrDefault(EntitySetting.SPINDLE_SPEED, 100); } public void setSpindleSpeed(Integer speed) { if (!valuesEquals(getSpindleSpeed(), speed)) { + if (speed == 0) { + speed = 100; + } settings.put(EntitySetting.SPINDLE_SPEED, speed); notifyListeners(EntitySetting.SPINDLE_SPEED); } @@ -205,17 +211,27 @@ public void setPasses(Integer passes) { } public int getFeedRate() { - return (Integer) settings.getOrDefault(EntitySetting.FEED_RATE, 50); + return (Integer) settings.getOrDefault(EntitySetting.FEED_RATE, getDefaultFeedRate()); } public void setFeedRate(Integer feedRate) { if (!valuesEquals(getFeedRate(), feedRate)) { - feedRate = Math.max(50, feedRate); + if (feedRate == 0) { + feedRate = getDefaultFeedRate(); + } settings.put(EntitySetting.FEED_RATE, feedRate); notifyListeners(EntitySetting.FEED_RATE); } } + private int getDefaultFeedRate() { + Controller controller = ControllerFactory.getController(); + if (controller != null && controller.getSettings() != null) { + return controller.getSettings().getFeedSpeed(); + } + return 50; + } + public String getFontFamily() { return (String) settings.getOrDefault(EntitySetting.FONT_FAMILY, Font.SANS_SERIF); } @@ -261,7 +277,7 @@ public void setSize(double width, double height) { } public boolean getLockRatio() { - return (Boolean) settings.getOrDefault(EntitySetting.LOCK_RATIO, true); + return (Boolean) settings.getOrDefault(EntitySetting.LOCK_RATIO, true); } public void setLockRatio(boolean lockRatio) { @@ -272,7 +288,7 @@ public void setLockRatio(boolean lockRatio) { } public void updateFromEntity(Group selectionGroup) { - if(selectionGroup.getChildren().size() > 1) { + if (selectionGroup.getChildren().size() > 1) { return; } boolean isTextCuttable = selectionGroup.getChildren().get(0) instanceof Text; diff --git a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/SimpleGcodeRouter.java b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/SimpleGcodeRouter.java index 4dbc62fe37..292ca9a104 100644 --- a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/SimpleGcodeRouter.java +++ b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/SimpleGcodeRouter.java @@ -70,13 +70,6 @@ public String toGcode(List entities) { Code.G94.name() + " ; units per minute feed rate mode\n" ); - if (settings.getSpindleSpeed() > 0) { - result.append(Code.M3.name()) - .append(" S" ) - .append(Math.round(settings.getSpindleSpeed())) - .append(" ; Turning on spindle\n" ); - } - result.append("\n" ); try { @@ -146,11 +139,9 @@ private GcodePath getGcodePathFromCuttables(List cuttables) { private String generateToolHeader() { return "; Tool: " + settings.getToolDiameter() + "mm\n" + "; Depth per pass: " + settings.getDepthPerPass() + "mm\n" + - "; Feed speed: " + settings.getFeedSpeed() + "mm/min\n" + "; Plunge speed: " + settings.getPlungeSpeed() + "mm/min\n" + "; Safe height: " + settings.getSafeHeight() + "mm\n" + - "; Tool step over: " + settings.getToolStepOver() + "mm\n" + - "; Spindle speed: " + Math.round(settings.getSpindleSpeed()) + "rpm\n"; + "; Tool step over: " + settings.getToolStepOver() + "mm\n"; } protected void toGcode(Writer writer, GcodePath path) throws IOException { @@ -168,13 +159,19 @@ protected void runPath(Writer writer, List segments) throws IOException writer.write(";" + s.getLabel() + "\n" ); } - if (s.spindleSpeed != null) { - writer.write("M3 S" + s.spindleSpeed + "\n" ); + if (s.getSpindleSpeed() != null) { + writer.write("M3 S" + s.getSpindleSpeed() + "\n" ); } switch (s.type) { // Seam are just markers. case SEAM: + if (!hasFeedRateSet && s.getFeedSpeed() != null) { + writer.write("F" ); + writer.write(String.valueOf(s.getFeedSpeed())); + writer.write(' '); + hasFeedRateSet = true; + } continue; // Rapid move @@ -196,6 +193,7 @@ protected void runPath(Writer writer, List segments) throws IOException writer.write("F" + settings.getPlungeSpeed() + " " ); writer.write(s.point.getFormattedGCode()); writer.write("\n" ); + hasFeedRateSet = false; break; // Motion at feed rate @@ -205,9 +203,9 @@ protected void runPath(Writer writer, List segments) throws IOException writer.write(s.type.gcode); writer.write(' '); - if (!hasFeedRateSet) { + if (!hasFeedRateSet && s.getFeedSpeed() != null) { writer.write("F" ); - writer.write(String.valueOf(settings.getFeedSpeed())); + writer.write(String.valueOf(s.getFeedSpeed())); writer.write(' '); hasFeedRateSet = true; } diff --git a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/path/GcodePath.java b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/path/GcodePath.java index 482f0eb56e..69c3a77676 100644 --- a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/path/GcodePath.java +++ b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/path/GcodePath.java @@ -51,6 +51,10 @@ public void addSegment(SegmentType type, PartialPosition point, String comment) segments.add(new Segment(type, point, comment)); } + public void addSegment(SegmentType type, PartialPosition point, int feedRate) { + segments.add(new Segment(type, point, null, null, feedRate)); + } + public void addSegment(Segment segment) { segments.add(segment); } diff --git a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/path/Segment.java b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/path/Segment.java index dacacc20c5..c047852ecd 100644 --- a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/path/Segment.java +++ b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/path/Segment.java @@ -43,13 +43,19 @@ public final class Segment { /** * The current spindle speed */ - public final Integer spindleSpeed; + private final Integer spindleSpeed; - public Segment(SegmentType type, PartialPosition point, String label, Integer spindleSpeed) { + /** + * The current feed speed + */ + private final Integer feedSpeed; + + public Segment(SegmentType type, PartialPosition point, String label, Integer spindleSpeed, Integer feedSpeed) { this.type = type; this.point = point; this.label = label; this.spindleSpeed = spindleSpeed; + this.feedSpeed = feedSpeed; } public Segment(SegmentType type, PartialPosition point) { @@ -60,7 +66,7 @@ public Segment(String label) { this(SegmentType.SEAM, null, label); } public Segment(SegmentType type, PartialPosition point, String label) { - this(type, point, label, null); + this(type, point, label, null, null); } /** @@ -93,4 +99,12 @@ public PartialPosition getPoint() { return point; } + + public Integer getSpindleSpeed() { + return spindleSpeed; + } + + public Integer getFeedSpeed() { + return feedSpeed; + } } diff --git a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/AbstractToolPath.java b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/AbstractToolPath.java index 7ae6f22b5a..eff3d39620 100644 --- a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/AbstractToolPath.java +++ b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/AbstractToolPath.java @@ -18,8 +18,10 @@ This file is part of Universal Gcode Sender (UGS). */ package com.willwinder.ugs.nbp.designer.io.gcode.toolpaths; +import com.willwinder.ugs.nbp.designer.entities.cuttable.Cuttable; import com.willwinder.ugs.nbp.designer.io.gcode.path.GcodePath; import com.willwinder.ugs.nbp.designer.io.gcode.path.PathGenerator; +import com.willwinder.ugs.nbp.designer.io.gcode.path.Segment; import com.willwinder.ugs.nbp.designer.io.gcode.path.SegmentType; import com.willwinder.ugs.nbp.designer.model.Settings; import com.willwinder.universalgcodesender.model.Axis; @@ -77,22 +79,24 @@ public GeometryFactory getGeometryFactory() { return geometryFactory; } - protected GcodePath toGcodePath(List> coordinateList) { - GcodePath gcodePath = new GcodePath(); + protected void addToGcodePath(GcodePath gcodePath, List> coordinateList, Cuttable source) { if (!coordinateList.isEmpty()) { + if (source.getSpindleSpeed() > 0) { + gcodePath.addSegment(new Segment(SegmentType.SEAM, null, null, (int) Math.round(settings.getMaxSpindleSpeed() * (source.getSpindleSpeed() / 100d)), null)); + } coordinateList.forEach(cl -> { if (!cl.isEmpty()) { addSafeHeightSegmentTo(gcodePath, cl.get(0)); gcodePath.addSegment(SegmentType.POINT, cl.get(0)); - cl.forEach(c -> gcodePath.addSegment(SegmentType.LINE, c)); + cl.forEach(c -> gcodePath.addSegment(SegmentType.LINE, c, source.getFeedRate())); } }); addSafeHeightSegment(gcodePath); } - return gcodePath; } + public GcodePath toGcodePath() { GcodePath gcodePath = new GcodePath(); appendGcodePath(gcodePath, settings); diff --git a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/LaserFillToolPath.java b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/LaserFillToolPath.java index 16b137f4aa..cb8a0b2dce 100644 --- a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/LaserFillToolPath.java +++ b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/LaserFillToolPath.java @@ -34,7 +34,7 @@ private List getGeometries() { } public void appendGcodePath(GcodePath gcodePath, Settings settings) { - gcodePath.addSegment(new Segment(SegmentType.SEAM, null, null, (int) Math.round(settings.getMaxSpindleSpeed() * (source.getSpindleSpeed() / 100d)))); + gcodePath.addSegment(new Segment(SegmentType.SEAM, null, null, (int) Math.round(settings.getMaxSpindleSpeed() * (source.getSpindleSpeed() / 100d)), source.getFeedRate())); List geometries = getGeometries(); geometries.forEach(g -> { diff --git a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/LaserOutlineToolPath.java b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/LaserOutlineToolPath.java index 3eceb56600..3d9e8d7811 100644 --- a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/LaserOutlineToolPath.java +++ b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/LaserOutlineToolPath.java @@ -20,7 +20,7 @@ public LaserOutlineToolPath(Settings settings, Cuttable source) { } public void appendGcodePath(GcodePath gcodePath, Settings settings) { - gcodePath.addSegment(new Segment(SegmentType.SEAM, null, null, (int) Math.round(settings.getMaxSpindleSpeed() * (source.getSpindleSpeed() / 100d)))); + gcodePath.addSegment(new Segment(SegmentType.SEAM, null, null, (int) Math.round(settings.getMaxSpindleSpeed() * (source.getSpindleSpeed() / 100d)), source.getFeedRate())); List geometries = getGeometries(); geometries.forEach(g -> addGeometrySegments(g, gcodePath)); diff --git a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/OutlineToolPath.java b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/OutlineToolPath.java index 9763a96cd1..c9ce037be5 100644 --- a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/OutlineToolPath.java +++ b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/OutlineToolPath.java @@ -80,6 +80,6 @@ public void appendGcodePath(GcodePath gcodePath, Settings settings) { } }); - gcodePath.appendGcodePath(toGcodePath(coordinateList)); + addToGcodePath(gcodePath, coordinateList, source); } } diff --git a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/PocketToolPath.java b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/PocketToolPath.java index fb096c21b4..a1721d7d8f 100644 --- a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/PocketToolPath.java +++ b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/PocketToolPath.java @@ -62,6 +62,6 @@ public void appendGcodePath(GcodePath gcodePath, Settings settings) { addGeometriesToCoordinatesList(shell, geometries, coordinateList, currentDepth); } - gcodePath.appendGcodePath(toGcodePath(coordinateList)); + addToGcodePath(gcodePath, coordinateList, source); } } diff --git a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/model/Settings.java b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/model/Settings.java index cd34089fe3..3e1d58a9f6 100644 --- a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/model/Settings.java +++ b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/model/Settings.java @@ -35,9 +35,9 @@ public class Settings { private UnitUtils.Units preferredUnits = UnitUtils.Units.MM; private double toolStepOver = 0.3; private double depthPerPass = 1; - private double spindleSpeed; private double laserDiameter = 0.2; private int maxSpindleSpeed = 255; + private boolean detectMaxSpindleSpeed = true; public Settings() { } @@ -167,15 +167,6 @@ public void setDepthPerPass(double depthPerPass) { notifyListeners(); } - public double getSpindleSpeed() { - return spindleSpeed; - } - - public void setSpindleSpeed(double spindleSpeed) { - this.spindleSpeed = Math.abs(spindleSpeed); - notifyListeners(); - } - public void applySettings(Settings settings) { if (settings == null) { return; @@ -189,9 +180,10 @@ public void applySettings(Settings settings) { setToolStepOver(settings.getToolStepOver()); setPreferredUnits(settings.getPreferredUnits()); setSafeHeight(settings.getSafeHeight()); - setSpindleSpeed(settings.getSpindleSpeed()); setLaserDiameter(settings.getLaserDiameter()); setMaxSpindleSpeed(settings.getMaxSpindleSpeed()); + setDetectMaxSpindleSpeed(settings.getDetectMaxSpindleSpeed()); + } public double getLaserDiameter() { @@ -208,7 +200,19 @@ public int getMaxSpindleSpeed() { } public void setMaxSpindleSpeed(int maxSpindleSpeed) { + if (this.maxSpindleSpeed == Math.abs(maxSpindleSpeed)) { + return; + } this.maxSpindleSpeed = Math.abs(maxSpindleSpeed); notifyListeners(); } + + public boolean getDetectMaxSpindleSpeed() { + return detectMaxSpindleSpeed; + } + + public void setDetectMaxSpindleSpeed(boolean detectMaxSpindleSpeed) { + this.detectMaxSpindleSpeed = detectMaxSpindleSpeed; + notifyListeners(); + } } diff --git a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/platform/DesignerTopComponent.java b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/platform/DesignerTopComponent.java index 5c8c25ade4..2c48431e53 100644 --- a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/platform/DesignerTopComponent.java +++ b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/platform/DesignerTopComponent.java @@ -28,7 +28,11 @@ This file is part of Universal Gcode Sender (UGS). import com.willwinder.ugs.nbp.designer.logic.ControllerFactory; import com.willwinder.ugs.nbp.lib.Mode; import com.willwinder.ugs.nbp.lib.lookup.CentralLookup; +import com.willwinder.universalgcodesender.firmware.FirmwareSettingsException; +import com.willwinder.universalgcodesender.listeners.UGSEventListener; import com.willwinder.universalgcodesender.model.BackendAPI; +import com.willwinder.universalgcodesender.model.UGSEvent; +import com.willwinder.universalgcodesender.model.events.FirmwareSettingEvent; import org.openide.awt.UndoRedo; import org.openide.cookies.CloseCookie; import org.openide.loaders.DataNode; @@ -51,7 +55,7 @@ This file is part of Universal Gcode Sender (UGS). persistenceType = TopComponent.PERSISTENCE_NEVER ) @TopComponent.Registration(mode = Mode.EDITOR_PRIMARY, openAtStartup = false) -public class DesignerTopComponent extends TopComponent implements UndoManagerListener, SelectionListener { +public class DesignerTopComponent extends TopComponent implements UndoManagerListener, SelectionListener, UGSEventListener { private static final long serialVersionUID = 3123334398723987873L; private static final Logger LOGGER = Logger.getLogger(DesignerTopComponent.class.getSimpleName()); private static DrawingContainer drawingContainer; @@ -64,6 +68,7 @@ public DesignerTopComponent(UgsDataObject dataObject) { super(); this.dataObject = dataObject; backend = CentralLookup.getDefault().lookup(BackendAPI.class); + backend.addUGSEventListener(this); controller = ControllerFactory.getController(); initSettingsAdapter(); @@ -80,6 +85,7 @@ public DesignerTopComponent(UgsDataObject dataObject) { loadDesign(dataObject); updateFilename(); PlatformUtils.registerActions(getActionMap(), this); + updateMaxSpindleSpeed(); } private void initSettingsAdapter() { @@ -141,6 +147,7 @@ protected void componentClosed() { controller.getUndoManager().removeListener(this); controller.release(); try { + backend.removeUGSEventListener(this); backend.unsetGcodeFile(); } catch (Exception e) { // Never mind @@ -178,4 +185,24 @@ public void onSelectionEvent(SelectionEvent selectionEvent) { PlatformUtils.openEntitesTree(controller); requestActive(); } + + @Override + public void UGSEvent(UGSEvent evt) { + if (evt instanceof FirmwareSettingEvent && controller.getSettings().getDetectMaxSpindleSpeed()) { + updateMaxSpindleSpeed(); + } + } + + private void updateMaxSpindleSpeed() { + if (!backend.isConnected()) { + return; + } + + try { + int maxSpindleSpeed = backend.getController().getFirmwareSettings().getMaxSpindleSpeed(); + controller.getSettings().setMaxSpindleSpeed(maxSpindleSpeed); + } catch (FirmwareSettingsException e) { + // Never mind... + } + } } diff --git a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/platform/SettingsAdapter.java b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/platform/SettingsAdapter.java index bf729b115c..b55e352b64 100644 --- a/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/platform/SettingsAdapter.java +++ b/ugs-platform/ugs-platform-plugin-designer/src/main/java/com/willwinder/ugs/nbp/designer/platform/SettingsAdapter.java @@ -29,6 +29,7 @@ This file is part of Universal Gcode Sender (UGS). public class SettingsAdapter { private static final Preferences preferences = NbPreferences.forModule(DesignerTopComponent.class); private static final String MAX_SPINDLE_SPEED = "maxSpindleSpeed"; + private static final String DETECT_MAX_SPINDLE_SPEED = "detectMaxSpindleSpeed"; private static final String LASER_DIAMETER = "laserDiameter"; private static final String FEED_SPEED = "feedSpeed"; private static final String PLUNGE_SPEED = "plungeSpeed"; @@ -36,7 +37,6 @@ public class SettingsAdapter { private static final String SAFE_HEIGHT = "safeHeight"; private static final String TOOL_STEP_OVER = "toolStepOver"; private static final String DEPTH_PER_PASS = "depthPerPass"; - private static final String SPINDLE_SPEED = "spindleSpeed"; private static final String STOCK_THICKNESS = "stockThickness"; private SettingsAdapter() {} @@ -44,6 +44,7 @@ private SettingsAdapter() {} public static Settings loadSettings() { Settings settings = new Settings(); settings.setMaxSpindleSpeed(preferences.getInt(MAX_SPINDLE_SPEED, 255)); + settings.setDetectMaxSpindleSpeed(preferences.getBoolean(DETECT_MAX_SPINDLE_SPEED, true)); settings.setLaserDiameter(preferences.getDouble(LASER_DIAMETER, 0.2d)); settings.setDepthPerPass(preferences.getDouble(DEPTH_PER_PASS, 1d)); settings.setFeedSpeed(preferences.getInt(FEED_SPEED, 1000)); @@ -51,13 +52,13 @@ public static Settings loadSettings() { settings.setToolDiameter(preferences.getDouble(TOOL_DIAMETER, 3d)); settings.setSafeHeight(preferences.getDouble(SAFE_HEIGHT, 5d)); settings.setToolStepOver(preferences.getDouble(TOOL_STEP_OVER, 0.3)); - settings.setSpindleSpeed(preferences.getDouble(SPINDLE_SPEED, 0.3)); settings.setStockThickness(preferences.getDouble(STOCK_THICKNESS, 10)); return settings; } public static void saveSettings(Settings settings) { preferences.putInt(MAX_SPINDLE_SPEED, settings.getMaxSpindleSpeed()); + preferences.putBoolean(DETECT_MAX_SPINDLE_SPEED, settings.getDetectMaxSpindleSpeed()); preferences.putDouble(LASER_DIAMETER, settings.getLaserDiameter()); preferences.putDouble(DEPTH_PER_PASS, settings.getDepthPerPass()); preferences.putInt(FEED_SPEED, settings.getFeedSpeed()); @@ -65,7 +66,6 @@ public static void saveSettings(Settings settings) { preferences.putDouble(TOOL_DIAMETER, settings.getToolDiameter()); preferences.putDouble(SAFE_HEIGHT, settings.getSafeHeight()); preferences.putDouble(TOOL_STEP_OVER, settings.getToolStepOver()); - preferences.putDouble(SPINDLE_SPEED, settings.getSpindleSpeed()); preferences.putDouble(STOCK_THICKNESS, settings.getStockThickness()); } } diff --git a/ugs-platform/ugs-platform-plugin-designer/src/test/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/LaserOutlinePathTest.java b/ugs-platform/ugs-platform-plugin-designer/src/test/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/LaserOutlinePathTest.java index 8456b21a32..792b274e32 100644 --- a/ugs-platform/ugs-platform-plugin-designer/src/test/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/LaserOutlinePathTest.java +++ b/ugs-platform/ugs-platform-plugin-designer/src/test/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/LaserOutlinePathTest.java @@ -1,11 +1,90 @@ package com.willwinder.ugs.nbp.designer.io.gcode.toolpaths; -import static org.junit.Assert.assertTrue; +import com.willwinder.ugs.nbp.designer.entities.cuttable.Rectangle; +import com.willwinder.ugs.nbp.designer.io.gcode.path.GcodePath; +import com.willwinder.ugs.nbp.designer.io.gcode.path.Segment; +import com.willwinder.ugs.nbp.designer.io.gcode.path.SegmentType; +import com.willwinder.ugs.nbp.designer.model.Settings; +import com.willwinder.ugs.nbp.designer.model.Size; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import org.junit.Test; +import java.util.List; + public class LaserOutlinePathTest { @Test - public void pocketOnRectangleWithHole() { - assertTrue(true); + public void outlineToolPathWithNoPassesShouldNotGenerateTheShape() { + Rectangle rectangle = new Rectangle(0,0); + rectangle.setFeedRate(100); + rectangle.setSpindleSpeed(100); + rectangle.setSize(new Size(10, 10)); + + Settings settings = new Settings(); + settings.setMaxSpindleSpeed(10000); + + LaserOutlineToolPath toolPath = new LaserOutlineToolPath(settings, rectangle); + toolPath.setStartDepth(-1); + toolPath.setTargetDepth(-1); + GcodePath gcodePath = toolPath.toGcodePath(); + + List segments = gcodePath.getSegments(); + + assertEquals(SegmentType.SEAM, segments.get(0).type); + assertNull(segments.get(0).point); + assertEquals(10000, segments.get(0).getSpindleSpeed(), 0.01); + + assertEquals(1, segments.size()); + } + + @Test + public void outlineToolPathWithOnePass() { + Rectangle rectangle = new Rectangle(0,0); + rectangle.setFeedRate(500); + rectangle.setSpindleSpeed(50); + rectangle.setSize(new Size(10, 10)); + rectangle.setPasses(1); + + Settings settings = new Settings(); + settings.setMaxSpindleSpeed(10000); + + LaserOutlineToolPath toolPath = new LaserOutlineToolPath(settings, rectangle); + toolPath.setStartDepth(-1); + toolPath.setTargetDepth(-1); + GcodePath gcodePath = toolPath.toGcodePath(); + + List segments = gcodePath.getSegments(); + + // Start spindle + assertEquals(SegmentType.SEAM, segments.get(0).type); + assertNull(segments.get(0).point); + assertEquals(5000, segments.get(0).getSpindleSpeed(), 0.01); + assertEquals(500, segments.get(0).getFeedSpeed(), 0.01); + + assertEquals(SegmentType.MOVE, segments.get(1).type); + assertEquals(0, segments.get(1).getPoint().getX(), 0.01); + assertEquals(0, segments.get(1).getPoint().getY(), 0.01); + + assertEquals(SegmentType.LINE, segments.get(2).type); + assertEquals(0, segments.get(2).getPoint().getX(), 0.01); + assertEquals(0, segments.get(2).getPoint().getY(), 0.01); + + assertEquals(SegmentType.LINE, segments.get(3).type); + assertEquals(0, segments.get(3).getPoint().getX(), 0.01); + assertEquals(10, segments.get(3).getPoint().getY(), 0.01); + + assertEquals(SegmentType.LINE, segments.get(4).type); + assertEquals(10, segments.get(4).getPoint().getX(), 0.01); + assertEquals(10, segments.get(4).getPoint().getY(), 0.01); + + assertEquals(SegmentType.LINE, segments.get(5).type); + assertEquals(10, segments.get(5).getPoint().getX(), 0.01); + assertEquals(0, segments.get(5).getPoint().getY(), 0.01); + + assertEquals(SegmentType.LINE, segments.get(6).type); + assertEquals(0, segments.get(6).getPoint().getX(), 0.01); + assertEquals(0, segments.get(6).getPoint().getY(), 0.01); + + assertEquals(7, segments.size()); } } diff --git a/ugs-platform/ugs-platform-plugin-designer/src/test/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/OutlineToolPathTest.java b/ugs-platform/ugs-platform-plugin-designer/src/test/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/OutlineToolPathTest.java index 64e5fd298a..2ad43ebced 100644 --- a/ugs-platform/ugs-platform-plugin-designer/src/test/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/OutlineToolPathTest.java +++ b/ugs-platform/ugs-platform-plugin-designer/src/test/java/com/willwinder/ugs/nbp/designer/io/gcode/toolpaths/OutlineToolPathTest.java @@ -97,4 +97,98 @@ public void toGcodePathShouldGenerateGcodeFromStartDepth() { assertEquals(10, segments.size()); } + + @Test + public void toGcodePathShouldAddFeedRate() { + Rectangle rectangle = new Rectangle(0,0); + rectangle.setFeedRate(100); + rectangle.setSize(new Size(10, 10)); + Settings settings = new Settings(); + settings.setSafeHeight(10); + + OutlineToolPath toolPath = new OutlineToolPath(settings, rectangle); + toolPath.setStartDepth(-1); + toolPath.setTargetDepth(-1); + GcodePath gcodePath = toolPath.toGcodePath(); + + List segments = gcodePath.getSegments(); + + // Move to safe height + assertEquals(SegmentType.MOVE, segments.get(0).type); + assertFalse(segments.get(0).point.hasX()); + assertFalse(segments.get(0).point.hasY()); + assertEquals(10, segments.get(0).point.getZ(), 0.01); + + // Move in XY-place + assertEquals(SegmentType.MOVE, segments.get(1).type); + assertEquals(0, segments.get(1).point.getX(), 0.01); + assertEquals(0, segments.get(1).point.getY(), 0.01); + assertFalse(segments.get(1).point.hasZ()); + + // Move to Z zero + assertEquals(SegmentType.MOVE, segments.get(2).type); + assertFalse(segments.get(2).point.hasX()); + assertFalse(segments.get(2).point.hasY()); + assertEquals(0, segments.get(2).point.getZ(), 0.01); + + // Move into material + assertEquals(SegmentType.POINT, segments.get(3).type); + assertTrue(segments.get(3).point.hasX()); + assertTrue(segments.get(3).point.hasY()); + assertEquals(-1, segments.get(3).point.getZ(), 0.01); + + assertEquals(SegmentType.LINE, segments.get(4).type); + assertEquals(0, segments.get(4).point.getX(), 0.01); + assertEquals(0, segments.get(4).point.getY(), 0.01); + assertEquals(-1, segments.get(4).point.getZ(), 0.01); + assertEquals(100, segments.get(4).getFeedSpeed(), 0.01); + + assertEquals(SegmentType.LINE, segments.get(5).type); + assertEquals(0, segments.get(5).point.getX(), 0.01); + assertEquals(10, segments.get(5).point.getY(), 0.01); + assertEquals(-1, segments.get(5).point.getZ(), 0.01); + + assertEquals(SegmentType.LINE, segments.get(7).type); + assertEquals(10, segments.get(7).point.getX(), 0.01); + assertEquals(0, segments.get(7).point.getY(), 0.01); + assertEquals(-1, segments.get(7).point.getZ(), 0.01); + + assertEquals(SegmentType.LINE, segments.get(8).type); + assertEquals(0, segments.get(8).point.getX(), 0.01); + assertEquals(0, segments.get(8).point.getY(), 0.01); + assertEquals(-1, segments.get(8).point.getZ(), 0.01); + + // Move to safe height + assertEquals(SegmentType.MOVE, segments.get(9).type); + assertFalse(segments.get(9).point.hasX()); + assertFalse(segments.get(9).point.hasY()); + assertEquals(10, segments.get(9).point.getZ(), 0.01); + + assertEquals(10, segments.size()); + } + + @Test + public void toGcodePathShouldAddSpindleSpeed() { + Rectangle rectangle = new Rectangle(0,0); + rectangle.setFeedRate(100); + rectangle.setSpindleSpeed(100); + rectangle.setSize(new Size(10, 10)); + Settings settings = new Settings(); + settings.setSafeHeight(10); + settings.setMaxSpindleSpeed(10000); + + OutlineToolPath toolPath = new OutlineToolPath(settings, rectangle); + toolPath.setStartDepth(-1); + toolPath.setTargetDepth(-1); + GcodePath gcodePath = toolPath.toGcodePath(); + + List segments = gcodePath.getSegments(); + + // Start spindle + assertEquals(SegmentType.SEAM, segments.get(0).type); + assertNull(segments.get(0).point); + assertEquals(10000, segments.get(0).getSpindleSpeed(), 0.01); + + assertEquals(11, segments.size()); + } } \ No newline at end of file