Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reworked the overrides panel #2446

Merged
merged 4 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ This file is part of Universal Gcode Sender (UGS).

import com.google.gson.JsonObject;
import com.willwinder.universalgcodesender.communicator.ICommunicator;
import com.willwinder.universalgcodesender.firmware.IOverrideManager;
import com.willwinder.universalgcodesender.firmware.g2core.G2CoreOverrideManager;
import com.willwinder.universalgcodesender.listeners.ControllerState;
import com.willwinder.universalgcodesender.listeners.ControllerStatus;
import com.willwinder.universalgcodesender.listeners.ControllerStatusBuilder;
import com.willwinder.universalgcodesender.listeners.MessageType;
import com.willwinder.universalgcodesender.model.CommunicatorState;
import com.willwinder.universalgcodesender.model.PartialPosition;

import static com.willwinder.universalgcodesender.model.CommunicatorState.COMM_IDLE;
import com.willwinder.universalgcodesender.model.PartialPosition;

/**
* G2Core Control layer.
Expand All @@ -41,13 +42,16 @@ public class G2CoreController extends TinyGController {
* A temporary flag for emulating a JOG state when parsing the controller status
*/
private boolean isJogging = false;
private final IOverrideManager overrideManager;

public G2CoreController() {
super();
overrideManager = new G2CoreOverrideManager(this, getCommunicator());
}

public G2CoreController(ICommunicator communicator) {
super(communicator);
overrideManager = new G2CoreOverrideManager(this, communicator);
}

@Override
Expand Down Expand Up @@ -90,7 +94,7 @@ protected void handleReadyResponse(String response, JsonObject jo) {
capabilities.addCapability(CapabilitiesConstants.CONTINUOUS_JOGGING);
capabilities.addCapability(CapabilitiesConstants.HOMING);
capabilities.addCapability(CapabilitiesConstants.FIRMWARE_SETTINGS);
capabilities.addCapability(CapabilitiesConstants.OVERRIDES);
capabilities.removeCapability(CapabilitiesConstants.OVERRIDES);
capabilities.removeCapability(CapabilitiesConstants.SETUP_WIZARD);

setCurrentState(COMM_IDLE);
Expand Down Expand Up @@ -191,4 +195,9 @@ protected ControllerStatus parseControllerStatus(JsonObject jo) {

return controllerStatus;
}

@Override
public IOverrideManager getOverrideManager() {
return overrideManager;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2013-2023 Will Winder
Copyright 2013-2024 Will Winder

This file is part of Universal Gcode Sender (UGS).

Expand Down Expand Up @@ -33,7 +33,8 @@ This file is part of Universal Gcode Sender (UGS).
import com.willwinder.universalgcodesender.model.Alarm;
import com.willwinder.universalgcodesender.model.Axis;
import com.willwinder.universalgcodesender.model.CommunicatorState;
import com.willwinder.universalgcodesender.model.Overrides;
import static com.willwinder.universalgcodesender.model.CommunicatorState.COMM_CHECK;
import static com.willwinder.universalgcodesender.model.CommunicatorState.COMM_IDLE;
import com.willwinder.universalgcodesender.model.PartialPosition;
import com.willwinder.universalgcodesender.model.Position;
import com.willwinder.universalgcodesender.model.UnitUtils.Units;
Expand All @@ -42,16 +43,15 @@ This file is part of Universal Gcode Sender (UGS).
import com.willwinder.universalgcodesender.types.GrblSettingMessage;
import com.willwinder.universalgcodesender.utils.ControllerUtils;
import com.willwinder.universalgcodesender.utils.GrblLookups;
import com.willwinder.universalgcodesender.firmware.grbl.GrblOverrideManager;
import com.willwinder.universalgcodesender.firmware.IOverrideManager;
import com.willwinder.universalgcodesender.utils.ThreadHelper;
import org.apache.commons.lang3.StringUtils;

import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;

import static com.willwinder.universalgcodesender.model.CommunicatorState.COMM_CHECK;
import static com.willwinder.universalgcodesender.model.CommunicatorState.COMM_IDLE;

/**
* GRBL Control layer, coordinates all aspects of control.
*
Expand All @@ -63,10 +63,16 @@ public class GrblController extends AbstractController {
private static final GrblLookups ERRORS = new GrblLookups("error_codes");
private final StatusPollTimer positionPollTimer;
private final GrblFirmwareSettings firmwareSettings;
private final IOverrideManager overrideManager;
private GrblControllerInitializer initializer;
private Capabilities capabilities = new Capabilities();
// Polling state
private ControllerStatus controllerStatus = new ControllerStatus(ControllerState.DISCONNECTED, new Position(0, 0, 0, Units.MM), new Position(0, 0, 0, Units.MM));
private ControllerStatus controllerStatus = ControllerStatusBuilder.newInstance()
.setState(ControllerState.DISCONNECTED)
.setWorkCoord(Position.ZERO)
.setMachineCoord(Position.ZERO)
.build();

// Canceling state
private Boolean isCanceling = false; // Set for the position polling thread.
private int attemptsRemaining;
Expand All @@ -88,6 +94,7 @@ public GrblController(ICommunicator communicator) {
this.firmwareSettings = new GrblFirmwareSettings(this);
this.comm.addListener(firmwareSettings);
this.initializer = new GrblControllerInitializer(this);
this.overrideManager = new GrblOverrideManager(this, communicator);
}

public GrblController() {
Expand Down Expand Up @@ -556,6 +563,11 @@ public ControllerStatus getControllerStatus() {
return controllerStatus;
}

@Override
public IOverrideManager getOverrideManager() {
return overrideManager;
}

// No longer a listener event
private void handleStatusString(final String string) {
if (this.capabilities == null) {
Expand Down Expand Up @@ -641,15 +653,6 @@ protected void setControllerState(ControllerState controllerState) {
dispatchStatusString(controllerStatus);
}

@Override
public void sendOverrideCommand(Overrides command) throws Exception {
Byte realTimeCommand = GrblUtils.getOverrideForEnum(command, capabilities);
if (realTimeCommand != null) {
this.dispatchConsoleMessage(MessageType.INFO, String.format(">>> 0x%02x\n", realTimeCommand));
this.comm.sendByteImmediately(realTimeCommand);
}
}

@Override
public boolean getStatusUpdatesEnabled() {
return positionPollTimer.isEnabled();
Expand Down
86 changes: 65 additions & 21 deletions ugs-core/src/com/willwinder/universalgcodesender/GrblUtils.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2012-2023 Will Winder
Copyright 2012-2024 Will Winder

This file is part of Universal Gcode Sender (UGS).

Expand All @@ -21,22 +21,29 @@ This file is part of Universal Gcode Sender (UGS).

import com.willwinder.universalgcodesender.firmware.grbl.commands.GetStatusCommand;
import com.willwinder.universalgcodesender.firmware.grbl.commands.GrblSystemCommand;
import com.willwinder.universalgcodesender.listeners.AccessoryStates;
import com.willwinder.universalgcodesender.listeners.AccessoryStatesBuilder;
import com.willwinder.universalgcodesender.listeners.ControllerState;
import com.willwinder.universalgcodesender.listeners.ControllerStatus;
import com.willwinder.universalgcodesender.listeners.ControllerStatus.AccessoryStates;
import com.willwinder.universalgcodesender.listeners.ControllerStatus.EnabledPins;
import com.willwinder.universalgcodesender.listeners.ControllerStatus.OverridePercents;
import com.willwinder.universalgcodesender.listeners.ControllerStatusBuilder;
import com.willwinder.universalgcodesender.listeners.EnabledPins;
import com.willwinder.universalgcodesender.listeners.EnabledPinsBuilder;
import com.willwinder.universalgcodesender.listeners.MessageType;
import com.willwinder.universalgcodesender.model.*;
import com.willwinder.universalgcodesender.listeners.OverridePercents;
import com.willwinder.universalgcodesender.model.Alarm;
import com.willwinder.universalgcodesender.model.Axis;
import com.willwinder.universalgcodesender.model.Overrides;
import com.willwinder.universalgcodesender.model.PartialPosition;
import com.willwinder.universalgcodesender.model.Position;
import com.willwinder.universalgcodesender.model.UnitUtils.Units;
import static com.willwinder.universalgcodesender.utils.ControllerUtils.sendAndWaitForCompletion;
import static com.willwinder.universalgcodesender.utils.ControllerUtils.sendAndWaitForCompletionWithRetry;
import org.apache.commons.lang3.StringUtils;

import java.util.Optional;
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;

/**
* Collection of useful Grbl related utilities.
*
Expand Down Expand Up @@ -347,10 +354,11 @@ static protected ControllerStatus getStatusFromStatusString(
public static ControllerStatus getStatusFromStatusStringLegacy(String status, Units reportingUnits) {
String stateString = StringUtils.defaultString(getStateFromStatusString(status), "unknown");
ControllerState state = getControllerStateFromStateString(stateString);
return new ControllerStatus(
state,
getMachinePositionFromStatusString(status, reportingUnits),
getWorkPositionFromStatusString(status, reportingUnits));
return ControllerStatusBuilder.newInstance()
.setState(state)
.setWorkCoord(getWorkPositionFromStatusString(status, reportingUnits))
.setMachineCoord(getMachinePositionFromStatusString(status, reportingUnits))
.build();
}

/**
Expand Down Expand Up @@ -404,13 +412,7 @@ else if (part.startsWith("WCO:")) {
}
else if (part.startsWith("Ov:")) {
isOverrideReport = true;
String[] overrideParts = part.substring(3).trim().split(",");
if (overrideParts.length == 3) {
overrides = new OverridePercents(
Integer.parseInt(overrideParts[0]),
Integer.parseInt(overrideParts[1]),
Integer.parseInt(overrideParts[2]));
}
overrides = parseOverrides(part).orElse(OverridePercents.EMTPY_OVERRIDE_PERCENTS);
}
else if (part.startsWith("F:")) {
feedSpeed = parseFeedSpeed(part);
Expand All @@ -422,11 +424,11 @@ else if (part.startsWith("FS:")) {
}
else if (part.startsWith("Pn:")) {
String value = part.substring(part.indexOf(':')+1);
pins = new EnabledPins(value);
pins = parseEnabledPins(value);
}
else if (part.startsWith("A:")) {
String value = part.substring(part.indexOf(':')+1);
accessoryStates = new AccessoryStates(value);
accessoryStates = parseAccessoryStates(value);
}
}

Expand Down Expand Up @@ -461,6 +463,48 @@ else if (part.startsWith("A:")) {
return new ControllerStatus(state, subStateString, MPos, WPos, feedSpeed, reportingUnits, spindleSpeed, overrides, WCO, pins, accessoryStates);
}

private static Optional<OverridePercents> parseOverrides(String value) {
String[] overrideParts = value.substring(3).trim().split(",");
if (overrideParts.length == 3) {
return Optional.of(new OverridePercents(
Integer.parseInt(overrideParts[0]),
Integer.parseInt(overrideParts[1]),
Integer.parseInt(overrideParts[2])));
}
return Optional.empty();
}

private static EnabledPins parseEnabledPins(String value) {
String enabledUpper = value.toUpperCase();
return new EnabledPinsBuilder()
.setX(enabledUpper.contains("X"))
.setY(enabledUpper.contains("Y"))
.setZ(enabledUpper.contains("Z"))
.setA(enabledUpper.contains("A"))
.setB(enabledUpper.contains("B"))
.setC(enabledUpper.contains("C"))
.setProbe(enabledUpper.contains("P"))
.setDoor(enabledUpper.contains("D"))
.setHold(enabledUpper.contains("H"))
.setSoftReset(enabledUpper.contains("R"))
.setCycleStart(enabledUpper.contains("S"))
.createEnabledPins();
}

/**
* Parses the accessory state string
*
* @param accessoryStates as a string
* @return the parsed accessory state
*/
private static AccessoryStates parseAccessoryStates(String accessoryStates) {
String enabledUpper = accessoryStates.toUpperCase();
boolean spindleCW = enabledUpper.contains("S");
boolean flood = enabledUpper.contains("F");
boolean mist = enabledUpper.contains("M");
return new AccessoryStatesBuilder().setSpindleCW(spindleCW).setFlood(flood).setMist(mist).createAccessoryStates();
}

/**
* Parses the feed speed from a status string starting with "F:".
* The supported formats are F:1000.0 or F:3000.0,100.0,100.0 which are current feed rate, requested feed rate and override feed rate
Expand Down
18 changes: 10 additions & 8 deletions ugs-core/src/com/willwinder/universalgcodesender/IController.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2015-2023 Will Winder
Copyright 2015-2024 Will Winder

This file is part of Universal Gcode Sender (UGS).

Expand All @@ -26,13 +26,13 @@ This file is part of Universal Gcode Sender (UGS).
import com.willwinder.universalgcodesender.listeners.ControllerListener;
import com.willwinder.universalgcodesender.listeners.ControllerStatus;
import com.willwinder.universalgcodesender.model.Axis;
import com.willwinder.universalgcodesender.model.Overrides;
import com.willwinder.universalgcodesender.model.PartialPosition;
import com.willwinder.universalgcodesender.model.CommunicatorState;
import com.willwinder.universalgcodesender.model.PartialPosition;
import com.willwinder.universalgcodesender.model.UnitUtils;
import com.willwinder.universalgcodesender.services.MessageService;
import com.willwinder.universalgcodesender.types.GcodeCommand;
import com.willwinder.universalgcodesender.utils.IGcodeStreamReader;
import com.willwinder.universalgcodesender.firmware.IOverrideManager;

import java.util.Optional;

Expand Down Expand Up @@ -129,11 +129,6 @@ public interface IController {
void probe(String axis, double feedRate, double distance, UnitUtils.Units units) throws Exception;
void offsetTool(String axis, double offset, UnitUtils.Units units) throws Exception;

/*
Overrides
*/
void sendOverrideCommand(Overrides command) throws Exception;

/*
Behavior
*/
Expand Down Expand Up @@ -246,4 +241,11 @@ public interface IController {
* @return a command creator for this controller
*/
ICommandCreator getCommandCreator();

/**
* Gets the manager for handling overrides.
*
* @return the override manager.
*/
IOverrideManager getOverrideManager();
}
Loading
Loading