From 19430be64dd0c82ad715344a602e290d59993f93 Mon Sep 17 00:00:00 2001 From: Joacim Breiler Date: Sun, 8 Dec 2024 09:30:12 +0100 Subject: [PATCH] Positive space capability (#2654) Add a capability for finding out if machine is working in positive space --- .../universalgcodesender/Capabilities.java | 30 +++--- .../CapabilitiesConstants.java | 22 ++++- .../universalgcodesender/GrblController.java | 4 +- .../GrblControllerInitializer.java | 9 +- .../universalgcodesender/GrblUtils.java | 13 ++- .../firmware/fluidnc/FluidNCController.java | 10 +- .../firmware/fluidnc/FluidNCUtils.java | 17 ++-- ...nCommand.java => GetBuildInfoCommand.java} | 4 +- .../firmware/grbl/GrblBuildOption.java | 57 +++++++++++ .../firmware/grbl/GrblBuildOptions.java | 44 +++++++++ .../grbl}/GrblCapabilitiesConstants.java | 6 +- .../firmware/grbl/GrblFirmwareSettings.java | 8 +- .../grbl/commands/GetBuildInfoCommand.java | 15 +++ .../resources/MessagesBundle_af_ZA.properties | 72 +++++++------- .../resources/MessagesBundle_it_IT.properties | 2 +- .../MessagesBundle_zh_Hans.properties | 6 +- .../GrblControllerTest.java | 98 +++++++------------ .../universalgcodesender/GrblUtilsTest.java | 11 ++- .../firmware/fluidnc/FluidNCUtilsTest.java | 14 +-- .../commands/GetBuildInfoCommandTest.java | 55 +++++++++++ .../GetFirmwareVersionCommandTest.java | 55 ----------- .../firmware/grbl/GrblBuildOptionsTest.java | 92 +++++++++++++++++ .../grbl/GrblFirmwareSettingsTest.java | 8 +- .../commands/GetBuildInfoCommandTest.java | 34 ++++++- .../core/windows/DiagnosticsTopComponent.java | 10 +- 25 files changed, 479 insertions(+), 217 deletions(-) rename ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/commands/{GetFirmwareVersionCommand.java => GetBuildInfoCommand.java} (97%) create mode 100644 ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblBuildOption.java create mode 100644 ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblBuildOptions.java rename ugs-core/src/com/willwinder/universalgcodesender/{ => firmware/grbl}/GrblCapabilitiesConstants.java (84%) create mode 100644 ugs-core/test/com/willwinder/universalgcodesender/firmware/fluidnc/commands/GetBuildInfoCommandTest.java delete mode 100644 ugs-core/test/com/willwinder/universalgcodesender/firmware/fluidnc/commands/GetFirmwareVersionCommandTest.java create mode 100644 ugs-core/test/com/willwinder/universalgcodesender/firmware/grbl/GrblBuildOptionsTest.java diff --git a/ugs-core/src/com/willwinder/universalgcodesender/Capabilities.java b/ugs-core/src/com/willwinder/universalgcodesender/Capabilities.java index bcc540dc7d..d06551dc11 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/Capabilities.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/Capabilities.java @@ -181,7 +181,6 @@ public boolean hasReturnToZero() { return hasCapability(CapabilitiesConstants.RETURN_TO_ZERO); } - /** * Returns if the controller has support for the given axis * @@ -189,22 +188,14 @@ public boolean hasReturnToZero() { * @return true if the axis is supported */ public boolean hasAxis(Axis axis) { - switch (axis) { - case X: - return hasCapability(CapabilitiesConstants.X_AXIS); - case Y: - return hasCapability(CapabilitiesConstants.Y_AXIS); - case Z: - return hasCapability(CapabilitiesConstants.Z_AXIS); - case A: - return hasCapability(CapabilitiesConstants.A_AXIS); - case B: - return hasCapability(CapabilitiesConstants.B_AXIS); - case C: - return hasCapability(CapabilitiesConstants.C_AXIS); - default: - return false; - } + return switch (axis) { + case X -> hasCapability(CapabilitiesConstants.X_AXIS); + case Y -> hasCapability(CapabilitiesConstants.Y_AXIS); + case Z -> hasCapability(CapabilitiesConstants.Z_AXIS); + case A -> hasCapability(CapabilitiesConstants.A_AXIS); + case B -> hasCapability(CapabilitiesConstants.B_AXIS); + case C -> hasCapability(CapabilitiesConstants.C_AXIS); + }; } /** @@ -215,4 +206,9 @@ public boolean hasAxis(Axis axis) { public boolean hasOpenDoor() { return hasCapability(CapabilitiesConstants.OPEN_DOOR); } + + @Override + public String toString() { + return String.join(", ", capabilities); + } } diff --git a/ugs-core/src/com/willwinder/universalgcodesender/CapabilitiesConstants.java b/ugs-core/src/com/willwinder/universalgcodesender/CapabilitiesConstants.java index 080697b9ce..62194b038a 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/CapabilitiesConstants.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/CapabilitiesConstants.java @@ -76,9 +76,10 @@ public class CapabilitiesConstants { public static final String RETURN_TO_ZERO = "RETURN_TO_ZERO"; /** - * A key for identifying if the firmware supports opening the door + * A key for identifying if the firmware supports triggering the DOOR state + * from the sender. */ - public static final String OPEN_DOOR = "DOOR_DOOR"; + public static final String OPEN_DOOR = "OPEN_DOOR"; public static final String X_AXIS = "X_AXIS"; public static final String Y_AXIS = "Y_AXIS"; @@ -91,4 +92,21 @@ public class CapabilitiesConstants { * A key for identifying if the firmware supports handling the device file system */ public static final String FILE_SYSTEM = "FILE_SYSTEM"; + + /** + * Traditionally CNC:s works in a negative machine space. When the machine is homed it is usually done + * in the right, far, upper corner which is then set to 0, therefore all coordinates in the machine space is + * defined with negative values. + *

+ * Some controllers have the option to inverse this, making the machine zero at the left, lower, close corner of + * the machine. + *

+ * By defining this capability we can account for this in the visualizer. + */ + public static final String MACHINE_POSITION_IN_POSITIVE_SPACE = "MACHINE_POSITION_IN_POSITIVE_SPACE"; + + /** + * Does the controller support variable spindles (typically PWM or through RS484 interfaces) + */ + public static final String VARIABLE_SPINDLE = "VARIABLE_SPINDLE"; } diff --git a/ugs-core/src/com/willwinder/universalgcodesender/GrblController.java b/ugs-core/src/com/willwinder/universalgcodesender/GrblController.java index 46523e3a63..b77f27294d 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/GrblController.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/GrblController.java @@ -22,6 +22,7 @@ This file is part of Universal Gcode Sender (UGS). import com.willwinder.universalgcodesender.communicator.ICommunicator; import com.willwinder.universalgcodesender.connection.ConnectionDriver; import com.willwinder.universalgcodesender.firmware.IFirmwareSettings; +import com.willwinder.universalgcodesender.firmware.grbl.GrblCapabilitiesConstants; import com.willwinder.universalgcodesender.firmware.grbl.GrblCommandCreator; import com.willwinder.universalgcodesender.firmware.grbl.GrblFirmwareSettings; import com.willwinder.universalgcodesender.firmware.grbl.GrblFirmwareSettingsInterceptor; @@ -192,7 +193,8 @@ private void initialize() { return; } - capabilities = GrblUtils.getGrblStatusCapabilities(initializer.getVersion().getVersionNumber(), initializer.getVersion().getVersionLetter()); + capabilities = GrblUtils.getGrblStatusCapabilities(initializer.getVersion().getVersionNumber(), initializer.getVersion().getVersionLetter(), initializer.getOptions()); + logger.info("Identified controller capabilities: " + capabilities); // Toggle the state to force UI update setControllerState(ControllerState.CONNECTING); diff --git a/ugs-core/src/com/willwinder/universalgcodesender/GrblControllerInitializer.java b/ugs-core/src/com/willwinder/universalgcodesender/GrblControllerInitializer.java index 983a904f23..1194e5b44f 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/GrblControllerInitializer.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/GrblControllerInitializer.java @@ -1,5 +1,6 @@ package com.willwinder.universalgcodesender; +import com.willwinder.universalgcodesender.firmware.grbl.GrblBuildOptions; import com.willwinder.universalgcodesender.firmware.grbl.GrblVersion; import com.willwinder.universalgcodesender.firmware.grbl.commands.GetBuildInfoCommand; import com.willwinder.universalgcodesender.firmware.grbl.commands.GetParserStateCommand; @@ -32,13 +33,14 @@ public class GrblControllerInitializer implements IControllerInitializer { private final AtomicBoolean isInitialized = new AtomicBoolean(false); private final GrblController controller; private GrblVersion version = GrblVersion.NO_VERSION; + private GrblBuildOptions options = new GrblBuildOptions(); public GrblControllerInitializer(GrblController controller) { this.controller = controller; } @Override - public boolean initialize() throws ControllerException{ + public boolean initialize() throws ControllerException { // Only allow one initialization at a time if (isInitializing.get() || isInitialized.get()) { return false; @@ -100,6 +102,7 @@ private void fetchControllerVersion() throws InterruptedException { } version = optionalVersion.get(); + options = getBuildInfoCommand.getBuildOptions(); } @Override @@ -121,4 +124,8 @@ public boolean isInitializing() { public GrblVersion getVersion() { return version; } + + public GrblBuildOptions getOptions() { + return options; + } } diff --git a/ugs-core/src/com/willwinder/universalgcodesender/GrblUtils.java b/ugs-core/src/com/willwinder/universalgcodesender/GrblUtils.java index d17cb96caa..eeea7cf680 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/GrblUtils.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/GrblUtils.java @@ -19,6 +19,9 @@ This file is part of Universal Gcode Sender (UGS). package com.willwinder.universalgcodesender; +import com.willwinder.universalgcodesender.firmware.grbl.GrblCapabilitiesConstants; +import com.willwinder.universalgcodesender.firmware.grbl.GrblBuildOption; +import com.willwinder.universalgcodesender.firmware.grbl.GrblBuildOptions; import com.willwinder.universalgcodesender.firmware.grbl.commands.GetStatusCommand; import com.willwinder.universalgcodesender.firmware.grbl.commands.GrblSystemCommand; import com.willwinder.universalgcodesender.listeners.AccessoryStates; @@ -232,7 +235,7 @@ protected static String getViewParserStateCommand(final double version, final Ch /** * Determines version of GRBL position capability. */ - protected static Capabilities getGrblStatusCapabilities(final double version, final Character letter) { + protected static Capabilities getGrblStatusCapabilities(final double version, final Character letter, GrblBuildOptions options) { Capabilities ret = new Capabilities(); ret.addCapability(CapabilitiesConstants.JOGGING); ret.addCapability(CapabilitiesConstants.CHECK_MODE); @@ -266,6 +269,14 @@ protected static Capabilities getGrblStatusCapabilities(final double version, fi ret.addCapability(CapabilitiesConstants.OPEN_DOOR); } + if (options.isEnabled(GrblBuildOption.HOMING_FORCE_ORIGIN_ENABLED)) { + ret.addCapability(CapabilitiesConstants.MACHINE_POSITION_IN_POSITIVE_SPACE); + } + + if (options.isEnabled(GrblBuildOption.VARIABLE_SPINDLE_ENABLED)) { + ret.addCapability(CapabilitiesConstants.VARIABLE_SPINDLE); + } + return ret; } diff --git a/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/FluidNCController.java b/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/FluidNCController.java index 5ecfe6bea8..bbe3a3217a 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/FluidNCController.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/FluidNCController.java @@ -21,7 +21,6 @@ This file is part of Universal Gcode Sender (UGS). import com.willwinder.universalgcodesender.Capabilities; import com.willwinder.universalgcodesender.ConnectionWatchTimer; import com.willwinder.universalgcodesender.ControllerException; -import com.willwinder.universalgcodesender.GrblCapabilitiesConstants; import com.willwinder.universalgcodesender.GrblUtils; import com.willwinder.universalgcodesender.IController; import com.willwinder.universalgcodesender.IFileService; @@ -41,12 +40,13 @@ This file is part of Universal Gcode Sender (UGS). import com.willwinder.universalgcodesender.firmware.fluidnc.commands.DetectEchoCommand; import com.willwinder.universalgcodesender.firmware.fluidnc.commands.FluidNCCommand; import com.willwinder.universalgcodesender.firmware.fluidnc.commands.GetAlarmCodesCommand; +import com.willwinder.universalgcodesender.firmware.fluidnc.commands.GetBuildInfoCommand; import com.willwinder.universalgcodesender.firmware.fluidnc.commands.GetErrorCodesCommand; -import com.willwinder.universalgcodesender.firmware.fluidnc.commands.GetFirmwareVersionCommand; import com.willwinder.universalgcodesender.firmware.fluidnc.commands.GetParserStateCommand; import com.willwinder.universalgcodesender.firmware.fluidnc.commands.GetStartupMessagesCommand; import com.willwinder.universalgcodesender.firmware.fluidnc.commands.GetStatusCommand; import com.willwinder.universalgcodesender.firmware.fluidnc.commands.SystemCommand; +import com.willwinder.universalgcodesender.firmware.grbl.GrblCapabilitiesConstants; import com.willwinder.universalgcodesender.firmware.grbl.GrblOverrideManager; import com.willwinder.universalgcodesender.gcode.GcodeParser; import com.willwinder.universalgcodesender.gcode.GcodeState; @@ -582,9 +582,9 @@ private void disableEcho() throws Exception { private void queryFirmwareVersion() throws Exception { // A sleep is required to make the next query reliable Thread.sleep(200); - GetFirmwareVersionCommand getFirmwareVersionCommand = FluidNCUtils.queryFirmwareVersion(this, messageService); - semanticVersion = getFirmwareVersionCommand.getVersion(); - firmwareVariant = getFirmwareVersionCommand.getFirmware(); + GetBuildInfoCommand getBuildInfoCommand = FluidNCUtils.queryBuildInformation(this, messageService); + semanticVersion = getBuildInfoCommand.getVersion(); + firmwareVariant = getBuildInfoCommand.getFirmware(); capabilities.addCapability(GrblCapabilitiesConstants.V1_FORMAT); } diff --git a/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/FluidNCUtils.java b/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/FluidNCUtils.java index 692985d2f8..f3d0d49be1 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/FluidNCUtils.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/FluidNCUtils.java @@ -7,7 +7,7 @@ import com.willwinder.universalgcodesender.firmware.FirmwareSetting; import com.willwinder.universalgcodesender.firmware.FirmwareSettingsException; import com.willwinder.universalgcodesender.firmware.IFirmwareSettings; -import com.willwinder.universalgcodesender.firmware.fluidnc.commands.GetFirmwareVersionCommand; +import com.willwinder.universalgcodesender.firmware.fluidnc.commands.GetBuildInfoCommand; import com.willwinder.universalgcodesender.firmware.fluidnc.commands.GetStatusCommand; import com.willwinder.universalgcodesender.firmware.fluidnc.commands.SystemCommand; import com.willwinder.universalgcodesender.listeners.ControllerState; @@ -16,6 +16,8 @@ import com.willwinder.universalgcodesender.model.Position; import com.willwinder.universalgcodesender.model.UnitUtils; import com.willwinder.universalgcodesender.services.MessageService; +import static com.willwinder.universalgcodesender.utils.ControllerUtils.sendAndWaitForCompletion; +import static com.willwinder.universalgcodesender.utils.ControllerUtils.sendAndWaitForCompletionWithRetry; import com.willwinder.universalgcodesender.utils.SemanticVersion; import org.apache.commons.lang3.StringUtils; @@ -24,9 +26,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import static com.willwinder.universalgcodesender.utils.ControllerUtils.sendAndWaitForCompletion; -import static com.willwinder.universalgcodesender.utils.ControllerUtils.sendAndWaitForCompletionWithRetry; - public class FluidNCUtils { public static final double GRBL_COMPABILITY_VERSION = 1.1d; public static final SemanticVersion MINIMUM_VERSION = new SemanticVersion(3, 3, 0); @@ -150,18 +149,18 @@ private static void addCapabilityIfSettingStartsWith(Capabilities capabilities, * @throws Exception if the command couldn't be sent * @throws IllegalStateException if the parsed version is not for a FluidNC controller or the version is too old */ - public static GetFirmwareVersionCommand queryFirmwareVersion(IController controller, MessageService messageService) throws Exception { + public static GetBuildInfoCommand queryBuildInformation(IController controller, MessageService messageService) throws Exception { messageService.dispatchMessage(MessageType.INFO, "*** Fetching device firmware version\n"); - GetFirmwareVersionCommand getFirmwareVersionCommand = sendAndWaitForCompletion(controller, new GetFirmwareVersionCommand()); - String firmwareVariant = getFirmwareVersionCommand.getFirmware(); - SemanticVersion semanticVersion = getFirmwareVersionCommand.getVersion(); + GetBuildInfoCommand getBuildInfoCommand = sendAndWaitForCompletion(controller, new GetBuildInfoCommand()); + String firmwareVariant = getBuildInfoCommand.getFirmware(); + SemanticVersion semanticVersion = getBuildInfoCommand.getVersion(); if (!firmwareVariant.equalsIgnoreCase("FluidNC") || semanticVersion.compareTo(MINIMUM_VERSION) < 0) { messageService.dispatchMessage(MessageType.INFO, String.format("*** Expected a 'FluidNC %s' or later but got '%s %s'\n", MINIMUM_VERSION, firmwareVariant, semanticVersion)); throw new IllegalStateException("Unknown controller version: " + semanticVersion.toString()); } - return getFirmwareVersionCommand; + return getBuildInfoCommand; } /** diff --git a/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/commands/GetFirmwareVersionCommand.java b/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/commands/GetBuildInfoCommand.java similarity index 97% rename from ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/commands/GetFirmwareVersionCommand.java rename to ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/commands/GetBuildInfoCommand.java index 0f2114c60d..dead7cbc52 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/commands/GetFirmwareVersionCommand.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/fluidnc/commands/GetBuildInfoCommand.java @@ -26,11 +26,11 @@ This file is part of Universal Gcode Sender (UGS). import java.util.regex.Matcher; import java.util.regex.Pattern; -public class GetFirmwareVersionCommand extends SystemCommand { +public class GetBuildInfoCommand extends SystemCommand { private static final Pattern VERSION_FLUIDNC_PATTERN = Pattern.compile("\\[VER:[0-9.]+ (?[a-zA-Z0-9]+) v?(?(?[0-9]*)(.(?[0-9]+)(.(?[0-9]+))?)?([a-zA-Z]+)?)(.*:.*)*]", Pattern.CASE_INSENSITIVE); private static final Pattern VERSION_GRBL_PATTERN = Pattern.compile("\\[VER:(?(?[0-9]*)(.(?[0-9]+)(.(?[0-9]+))?)).*]", Pattern.CASE_INSENSITIVE); - public GetFirmwareVersionCommand() { + public GetBuildInfoCommand() { super("$I"); } diff --git a/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblBuildOption.java b/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblBuildOption.java new file mode 100644 index 0000000000..258c620dc1 --- /dev/null +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblBuildOption.java @@ -0,0 +1,57 @@ +/* + 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.grbl; + +/** + * GRBL options are reported by the build info command ($I). This enum contains the known options. + */ +public enum GrblBuildOption { + VARIABLE_SPINDLE_ENABLED("V"), + LINE_NUMBERS_ENABLED("N"), + MIST_COOLANT_ENABLED("M"), + CORE_XY_ENABLED("C"), + PARKING_MOTION_ENABLED("P"), + HOMING_FORCE_ORIGIN_ENABLED("Z"), + HOMING_SINGLE_AXIS_COMMAND_ENABLED("H"), + TWO_LIMIT_SWITCHES_ON_AXIS_ENABLED("T"), + TWO_ALLOW_OVERRIDE_ON_PROBING_ENABLED("A"), + USE_SPINDLE_DIRECTION_AS_ENABLE_PIN_ENABLED("D"), + SPINDLE_OFF_ON_ZERO_SPEED_ENABLED("0"), + SOFTWARE_LIMIT_PIN_DEBOUNCING_ENABLED("S"), + PARKING_OVERRIDE_CONTROL_ENABLED("R"), + SAFETY_DOOR_INPUT_ENABLED("+"), + RESTORE_ALL_EEPROM_DISABLED("*"), + RESTORE_EEPROM_SETTINGS_DISABLED("$"), + RESTORE_EEPROM_PARAMETER_DATA_DISABLED("#"), + BUILD_INFO_USER_STRING_DISABLED("I"), + FORCE_SYNC_ON_EEPROM_WRITE_DISABLED("E"), + FORCE_SYNC_ON_WORK_COORDINATE_CHANGE_DISABLED("W"), + HOMING_INITIALIZATION_LOCK_DISABLED("L"), + DUAL_AXIS_MOTORS_ENABLED("2"); + + private final String code; + + GrblBuildOption(String code) { + this.code = code; + } + + public String getCode() { + return code; + } +} diff --git a/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblBuildOptions.java b/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblBuildOptions.java new file mode 100644 index 0000000000..30a09f76f2 --- /dev/null +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblBuildOptions.java @@ -0,0 +1,44 @@ +/* + 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.grbl; + +import org.apache.commons.lang3.StringUtils; + +/** + * Parses options from the build info command ($I) + * Documentation + * + * @author Joacim Breiler + */ +public class GrblBuildOptions { + private final String options; + + public GrblBuildOptions() { + this("[OPT:]"); + } + + public GrblBuildOptions(String options) { + this.options = options; + } + + public boolean isEnabled(GrblBuildOption grblBuildOption) { + String buildOptions = StringUtils.substringBefore(StringUtils.substringBetween(options, "[OPT:", "]"), ","); + return buildOptions.contains(grblBuildOption.getCode()); + } +} diff --git a/ugs-core/src/com/willwinder/universalgcodesender/GrblCapabilitiesConstants.java b/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblCapabilitiesConstants.java similarity index 84% rename from ugs-core/src/com/willwinder/universalgcodesender/GrblCapabilitiesConstants.java rename to ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblCapabilitiesConstants.java index 6b3e022b0b..4fb6e33df0 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/GrblCapabilitiesConstants.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblCapabilitiesConstants.java @@ -16,11 +16,11 @@ This file is part of Universal Gcode Sender (UGS). You should have received a copy of the GNU General Public License along with UGS. If not, see . */ -package com.willwinder.universalgcodesender; +package com.willwinder.universalgcodesender.firmware.grbl; /** - * Constants for defining additional capabilities from {@link CapabilitiesConstants} that a - * GRBL controller may support. The constants may be added to a {@link Capabilities} object. + * Constants for defining additional capabilities from {@link com.willwinder.universalgcodesender.CapabilitiesConstants} that a + * GRBL controller may support. The constants may be added to a {@link com.willwinder.universalgcodesender.Capabilities} object. * * @author Joacim Breiler */ 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 04feec9b13..ea54eb4c76 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblFirmwareSettings.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblFirmwareSettings.java @@ -407,8 +407,8 @@ private int getHomingInvertDirectionMask() { } @Override - public boolean isHomingEnabled() throws FirmwareSettingsException { - return getValueAsBoolean(KEY_HOMING_ENABLED); + public boolean isHomingEnabled() { + return getValueAsBoolean(KEY_HOMING_ENABLED, false); } @Override @@ -468,4 +468,8 @@ private boolean getValueAsBoolean(String key) throws FirmwareSettingsException { FirmwareSetting firmwareSetting = getSetting(key).orElseThrow(() -> new FirmwareSettingsException("Couldn't find setting with key: " + key)); return "1".equalsIgnoreCase(firmwareSetting.getValue()); } + + private boolean getValueAsBoolean(String key, boolean defaultValue) { + return getSetting(key).map(FirmwareSetting::getValue).map("1"::equalsIgnoreCase).orElse(defaultValue); + } } diff --git a/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/commands/GetBuildInfoCommand.java b/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/commands/GetBuildInfoCommand.java index ffb1e9d926..1d6dc01dd9 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/commands/GetBuildInfoCommand.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/commands/GetBuildInfoCommand.java @@ -19,6 +19,7 @@ This file is part of Universal Gcode Sender (UGS). package com.willwinder.universalgcodesender.firmware.grbl.commands; import com.willwinder.universalgcodesender.GrblUtils; +import com.willwinder.universalgcodesender.firmware.grbl.GrblBuildOptions; import com.willwinder.universalgcodesender.firmware.grbl.GrblVersion; import org.apache.commons.lang3.StringUtils; @@ -61,4 +62,18 @@ public Optional getVersion() { .map(GrblVersion::new) .findFirst(); } + + public GrblBuildOptions getBuildOptions() { + String[] lines = StringUtils.split(getResponse(), "\n"); + + if (lines.length == 2 && StringUtils.equals(lines[1], "ok")) { + return new GrblBuildOptions(); + } + + return Arrays.stream(lines) + .filter(line -> line.startsWith("[OPT:")) + .map(GrblBuildOptions::new) + .findFirst() + .orElse(new GrblBuildOptions()); + } } diff --git a/ugs-core/src/resources/MessagesBundle_af_ZA.properties b/ugs-core/src/resources/MessagesBundle_af_ZA.properties index c52d14db57..df07cc0616 100644 --- a/ugs-core/src/resources/MessagesBundle_af_ZA.properties +++ b/ugs-core/src/resources/MessagesBundle_af_ZA.properties @@ -12,20 +12,20 @@ help = Hulp save.close = Spaar en Maak toe unknown = onbekend mainWindow.helpDialog = Masjien Kontrole Hulp -mainWindow.resetZero = Herstel zero\\\: Verander die huidige kou00F6rdinate na zero sonder dat die masjien verskuif. -mainWindow.returnToZero = Terug na zero\\\: Beweeg masjien tot by lokasie 0, 0, 0. -mainWindow.softReset = Sagte Herstel\\\: Herstel GRBL staat sonder die om die posisie op te dateer. -mainWindow.homing = $ H\\\: Begin Inkorrel siklus. Dit benodig Grbl 0.8c vir volle ondersteuning -mainWindow.alarmLock = $ X\\\: Deaktiveer die GRBL alarm slot. -mainWindow.checkMode = $ C\\\: Skakel "check" operasie mode, waar GRBL die gcode ontleed maar nie die masjien beweeg nie. -mainWindow.getState = $ G\\\: Versoek staat inligting vanaf GRBL (resultaat verskuin op konsele). +mainWindow.resetZero = Herstel zero\: Verander die huidige kou00F6rdinate na zero sonder dat die masjien verskuif. +mainWindow.returnToZero = Terug na zero\: Beweeg masjien tot by lokasie 0, 0, 0. +mainWindow.softReset = Sagte Herstel\: Herstel GRBL staat sonder die om die posisie op te dateer. +mainWindow.homing = $H\: Begin Inkorrel siklus. Dit benodig Grbl 0.8c vir volle ondersteuning +mainWindow.alarmLock = $X\: Deaktiveer die GRBL alarm slot. +mainWindow.checkMode = $C\: Skakel "check" operasie mode, waar GRBL die gcode ontleed maar nie die masjien beweeg nie. +mainWindow.getState = $G\: Versoek staat inligting vanaf GRBL (resultaat verskuin op konsele). mainWindow.helpKeyboard = Sleutelbord Kontrole -mainWindow.helpKeyX = X\\\: Arrow Links/Regs; Sleutels Links/Regs ; Numeriese eiland\\\: 4/6 -mainWindow.helpKeyY = Y\\\: Arrow Up/Down; Sleutels Op/Af; Numeriese eiland\\\: 8/2 -mainWindow.helpKeyZ = Z\\\: Page Up/Down; Sleutels Page Up/Down; Numeriese eiland\\\: 9/3 -mainWindow.helpKeyPlusMinus = Vermeerder/Verminder Stappe\\\: Sleutels +/- -mainWindow.helpKeyDivMul = Verander Stappe\\\: Sleutels DEEL DEUR/MAAL -mainWindow.helpKeyZero = Herstel Zero\\\: Sleutels Insert; Numeriese eiland \\\: 0 +mainWindow.helpKeyX = X\: Arrow Links/Regs; Sleutels Links/Regs ; Numeriese eiland\: 4/6 +mainWindow.helpKeyY = Y\: Arrow Up/Down; Sleutels Op/Af; Numeriese eiland\: 8/2 +mainWindow.helpKeyZ = Z\: Page Up/Down; Sleutels Page Up/Down; Numeriese eiland\: 9/3 +mainWindow.helpKeyPlusMinus = Vermeerder/Verminder Stappe\: Sleutels +/- +mainWindow.helpKeyDivMul = Verander Stappe\: Sleutels DEEL DEUR/MAAL +mainWindow.helpKeyZero = Herstel Zero\: Sleutels Insert; Numeriese eiland \: 0 mainWindow.status.hold = Hou mainWindow.status.queue = Tou mainWindow.status.run = Hardloop @@ -47,39 +47,39 @@ mainWindow.error.rxtxMac2 = gids genoem %s met die volgende opdragte mainWindow.ui.pauseButton = Wag mainWindow.ui.resumeButton = Hervat mainWindow.ui.jobComplete = Werk klaargemaak na -mainWindow.swing.activeStateLabel = Aktiewe Staat\\\: +mainWindow.swing.activeStateLabel = Aktiewe Staat\: mainWindow.swing.arrowMovementEnabled = Skakel aan Sleutelbord Beweging -mainWindow.swing.baudLabel = Baud\\\: +mainWindow.swing.baudLabel = Baud\: mainWindow.swing.browseButton = Loer mainWindow.swing.cancelButton = Kanselleer -mainWindow.swing.commandLabel = Opdrag\\\: +mainWindow.swing.commandLabel = Opdrag\: mainWindow.swing.connectionPanel = Konneksie mainWindow.swing.controlContextTabbedPane.commands = Opdragte mainWindow.swing.controlContextTabbedPane.fileMode = Lu00EAer Mode mainWindow.swing.controlContextTabbedPane.machineControl = Masjien Beheer mainWindow.swing.controlContextTabbedPane.macros = Makros -mainWindow.swing.durationLabel = Duur\\\: +mainWindow.swing.durationLabel = Duur\: mainWindow.swing.fileLabel = Lu00EAer -mainWindow.swing.firmwareLabel = Fermware\\\: +mainWindow.swing.firmwareLabel = Fermware\: mainWindow.swing.firmwareSettingsMenu = Fermware Stellings mainWindow.swing.grblConnectionSettingsMenuItem = Stuurder Stellings mainWindow.swing.settingsMenu = Stellings mainWindow.swing.statusPanel = Masjien status mainWindow.swing.bottomTabbedPane.console = Konsole mainWindow.swing.bottomTabbedPane.table = Opdrag Tabel -mainWindow.swing.latestCommentLabel = Laaste Kommentaar\\\: +mainWindow.swing.latestCommentLabel = Laaste Kommentaar\: mainWindow.swing.machinePosition = Masjien Posisie mainWindow.swing.opencloseButton = Maak Oop mainWindow.swing.pauseButton = Wag -mainWindow.swing.portLabel = Poort\\\: -mainWindow.swing.remainingRowsLabel = Oorblywende Rye\\\: -mainWindow.swing.remainingTimeLabel = Min of meer ongeveer Tyd wat oorbly\\\: +mainWindow.swing.portLabel = Poort\: +mainWindow.swing.remainingRowsLabel = Oorblywende Rye\: +mainWindow.swing.remainingTimeLabel = Min of meer ongeveer Tyd wat oorbly\: mainWindow.swing.resetCoordinatesButton = Herstel Zero mainWindow.swing.returnToZeroButton = Keer terug na Zero -mainWindow.swing.rowsLabel = Rye in Lu00EAer\\\: +mainWindow.swing.rowsLabel = Rye in Lu00EAer\: mainWindow.swing.scrollWindowCheckBox = Skrol uitset venster mainWindow.swing.sendButton = Stuur -mainWindow.swing.sentRowsLabel = Rye Gestuur\\\: +mainWindow.swing.sentRowsLabel = Rye Gestuur\: mainWindow.swing.showVerboseOutputCheckBox = Wys verbose uitset mainWindow.swing.softResetMachineControl = Sagte Herstel mainWindow.swing.stepSizeLabel = Trap groote @@ -111,18 +111,18 @@ sender.status.rate = Status pollering tempo (ms) sender.arcs = Omskep bou00EB na lyne sender.arcs.threshold = Klein boog drempel (mm) sender.arcs.length = Klein boor segment lengte (mm) -sender.help.speed.override = Skakel aan spoed oorskrywing\\\: Skakel die spoed oorskrywing aan of af. -sender.help.speed.percent = Spoed oorskrywing persentasie\\\: Faktor waarmee die spoed geskaal sal word -sender.help.command.length = Maks opdrag lengte\\\: Maskimum lengte van 'n opdrag voordat n fout boodskap opgebring sal word. -sender.help.truncate = Kapt desimale nommers\\\: Aantal nommers na die desimale punt want na die fermware toe gestuur sal word. -sender.help.singlestep = Skakel aan enkele stap mode\\\: DIt skakel aan enkele stap mode, en dit is baie stadig. -sender.help.whitespace = Verwyder alle witspasie\\\: Verwyder die witspasie wat gewoonlik onnodig is in g-kode opdragte. -sender.help.status = Skakel aan status pollering\\\: SKakel aan die pollering van fermware, indien dit moontlik is. -sender.help.status.rate = Status pollering tempo\\\: Die tempo in millisekondes waarteen status versoeke gestuur word. -sender.help.state = Staat kleur vertoning\\\: Die beheerder status word rooi/oranje/geel ingekleur, gebasseer op die huidige staat. -sender.help.arcs = Omskep bou00EB na lyne\\\: Omskep klein bou00EB opdragte (G2/G3) na 'n reeks van G1 opdragte. -sender.help.arcs.threshold = Klein boog drempel\\\: Die boog lengte (in mm) wat onder hierdie waarde is, sal na 'n reeks G1 opdragte omskep word. -sender.help.arcs.length = Klein boor segment lengte\\\: Die lengte (in mm) van segmente in 'n uitgebreide boog. +sender.help.speed.override = Skakel aan spoed oorskrywing\: Skakel die spoed oorskrywing aan of af. +sender.help.speed.percent = Spoed oorskrywing persentasie\: Faktor waarmee die spoed geskaal sal word +sender.help.command.length = Maks opdrag lengte\: Maskimum lengte van 'n opdrag voordat n fout boodskap opgebring sal word. +sender.help.truncate = Kapt desimale nommers\: Aantal nommers na die desimale punt want na die fermware toe gestuur sal word. +sender.help.singlestep = Skakel aan enkele stap mode\: DIt skakel aan enkele stap mode, en dit is baie stadig. +sender.help.whitespace = Verwyder alle witspasie\: Verwyder die witspasie wat gewoonlik onnodig is in g-kode opdragte. +sender.help.status = Skakel aan status pollering\: SKakel aan die pollering van fermware, indien dit moontlik is. +sender.help.status.rate = Status pollering tempo\: Die tempo in millisekondes waarteen status versoeke gestuur word. +sender.help.state = Staat kleur vertoning\: Die beheerder status word rooi/oranje/geel ingekleur, gebasseer op die huidige staat. +sender.help.arcs = Omskep bou00EB na lyne\: Omskep klein bou00EB opdragte (G2/G3) na 'n reeks van G1 opdragte. +sender.help.arcs.threshold = Klein boog drempel\: Die boog lengte (in mm) wat onder hierdie waarde is, sal na 'n reeks G1 opdragte omskep word. +sender.help.arcs.length = Klein boor segment lengte\: Die lengte (in mm) van segmente in 'n uitgebreide boog. sender.help.dialog.title = Stuurder Stellings Hulp communicator.exception.port = Geen drywer vir poort controller.exception.booting = Grbl het nog nie klaar gelaai nie. diff --git a/ugs-core/src/resources/MessagesBundle_it_IT.properties b/ugs-core/src/resources/MessagesBundle_it_IT.properties index ab9b44ef42..72408f5860 100644 --- a/ugs-core/src/resources/MessagesBundle_it_IT.properties +++ b/ugs-core/src/resources/MessagesBundle_it_IT.properties @@ -96,7 +96,7 @@ mainWindow.swing.showVerboseOutputCheckBox = Mostra uscita dettagliata mainWindow.swing.showCommandTableCheckBox = Attiva la tavola dei comandi mainWindow.swing.stepSizeLabel = Dimensione di passo XY\: mainWindow.swing.visualizeButton = Visualizza -mainWindow.swing.workPositionLabel = Posizione di Lavoro\\\: +mainWindow.swing.workPositionLabel = Posizione di Lavoro\: mainWindow.swing.macroInstructions = Ogni box può contenere una serie di comandi GCode separati da '';''.
Per eseguire il comando premi sul pulsante a sinistra del testo.

Sostituzioni interattive possono essere fatte con\: