From 7d9d6fc9c2169a5aaa3897a9af3dff71ef33a544 Mon Sep 17 00:00:00 2001 From: Joacim Breiler Date: Sat, 4 Jan 2025 09:46:43 +0100 Subject: [PATCH] Reset overrides before starting a new stream (#2669) --- .../firmware/AbstractOverrideManager.java | 15 ++++++ .../firmware/DefaultOverrideManager.java | 5 ++ .../firmware/IOverrideManager.java | 5 ++ .../firmware/grbl/GrblOverrideManager.java | 7 +++ .../GrblControllerTest.java | 14 +++-- .../grbl/GrblOverrideManagerTest.java | 54 +++++++++++++++++++ 6 files changed, 95 insertions(+), 5 deletions(-) diff --git a/ugs-core/src/com/willwinder/universalgcodesender/firmware/AbstractOverrideManager.java b/ugs-core/src/com/willwinder/universalgcodesender/firmware/AbstractOverrideManager.java index 0e5aa2570d..1287729023 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/firmware/AbstractOverrideManager.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/AbstractOverrideManager.java @@ -52,6 +52,21 @@ protected AbstractOverrideManager(IController controller, ICommunicator communic public void statusStringListener(ControllerStatus status) { onControllerStatus(status); } + + @Override + public void streamComplete() { + resetAll(); + } + + @Override + public void streamCanceled() { + resetAll(); + } + + @Override + public void streamStarted() { + resetAll(); + } }); } diff --git a/ugs-core/src/com/willwinder/universalgcodesender/firmware/DefaultOverrideManager.java b/ugs-core/src/com/willwinder/universalgcodesender/firmware/DefaultOverrideManager.java index a0e5c55665..fe59c6bbee 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/firmware/DefaultOverrideManager.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/DefaultOverrideManager.java @@ -116,6 +116,11 @@ public void setMessageService(MessageService messageService) { // Not implemented } + @Override + public void resetAll() { + // Not implemented + } + @Override public List getSliderSteps(OverrideType type) { return List.of(); diff --git a/ugs-core/src/com/willwinder/universalgcodesender/firmware/IOverrideManager.java b/ugs-core/src/com/willwinder/universalgcodesender/firmware/IOverrideManager.java index 10ba8ef651..336482eea2 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/firmware/IOverrideManager.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/IOverrideManager.java @@ -182,4 +182,9 @@ public interface IOverrideManager { void setRadioTarget(OverrideType type, int value); void setMessageService(MessageService messageService); + + /** + * Resets the overrides + */ + void resetAll(); } diff --git a/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblOverrideManager.java b/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblOverrideManager.java index 621ccc7eae..766ffd0cef 100644 --- a/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblOverrideManager.java +++ b/ugs-core/src/com/willwinder/universalgcodesender/firmware/grbl/GrblOverrideManager.java @@ -150,6 +150,13 @@ public void setMessageService(MessageService messageService) { this.messageService = messageService; } + @Override + public void resetAll() { + sendOverrideCommand(Overrides.CMD_RAPID_OVR_RESET); + sendOverrideCommand(Overrides.CMD_FEED_OVR_RESET); + sendOverrideCommand(Overrides.CMD_SPINDLE_OVR_RESET); + } + @Override public int getSliderDefault(OverrideType type) { return switch (type) { diff --git a/ugs-core/test/com/willwinder/universalgcodesender/GrblControllerTest.java b/ugs-core/test/com/willwinder/universalgcodesender/GrblControllerTest.java index 2bcaab6129..2070ce058a 100644 --- a/ugs-core/test/com/willwinder/universalgcodesender/GrblControllerTest.java +++ b/ugs-core/test/com/willwinder/universalgcodesender/GrblControllerTest.java @@ -35,6 +35,7 @@ This file is part of Universal Gcode Sender (UGS). import static com.willwinder.universalgcodesender.model.CommunicatorState.COMM_CHECK; import static com.willwinder.universalgcodesender.model.CommunicatorState.COMM_IDLE; import static com.willwinder.universalgcodesender.model.CommunicatorState.COMM_SENDING; +import com.willwinder.universalgcodesender.model.Overrides; import com.willwinder.universalgcodesender.model.PartialPosition; import com.willwinder.universalgcodesender.model.UnitUtils; import com.willwinder.universalgcodesender.services.MessageService; @@ -717,22 +718,22 @@ public void cancelSendOnDoorStateShouldCancelCommandAndIssueReset() throws Excep assertEquals(1, mgc.numCancelSendCalls); assertEquals(0, mgc.numPauseSendCalls); - assertEquals(0, mgc.sentBytes.size()); + assertEquals(3, mgc.sentBytes.size()); // First round we will store the last position instance.rawResponseHandler(""); assertEquals(1, mgc.numCancelSendCalls); assertEquals(0, mgc.numPauseSendCalls); - assertEquals(0, mgc.sentBytes.size()); + assertEquals(3, mgc.sentBytes.size()); // Now we will do the actual cancel instance.rawResponseHandler(""); assertEquals(2, mgc.numCancelSendCalls); assertEquals(0, mgc.numPauseSendCalls); - assertEquals(1, mgc.sentBytes.size()); - assertEquals(Byte.valueOf(GRBL_RESET_COMMAND), mgc.sentBytes.get(0)); + assertEquals(4, mgc.sentBytes.size()); + assertEquals(Byte.valueOf(GRBL_RESET_COMMAND), mgc.sentBytes.get(3)); } private void sendStuff(GrblController instance) throws Exception { @@ -1293,7 +1294,10 @@ public void errorInCheckModeSending() throws Exception { assertEquals(COMM_SENDING, gc.getCommunicatorState()); assertEquals(ControllerState.CHECK, gc.getControllerStatus().getState()); assertFalse(gc.isPaused()); - assertEquals(Byte.valueOf(GRBL_PAUSE_COMMAND), mgc.sentBytes.get(0)); + assertEquals(GrblUtils.getOverrideForEnum(Overrides.CMD_RAPID_OVR_RESET, gc.getCapabilities()), mgc.sentBytes.get(0)); + assertEquals(GrblUtils.getOverrideForEnum(Overrides.CMD_FEED_OVR_RESET, gc.getCapabilities()), mgc.sentBytes.get(1)); + assertEquals(GrblUtils.getOverrideForEnum(Overrides.CMD_SPINDLE_OVR_RESET, gc.getCapabilities()), mgc.sentBytes.get(2)); + assertEquals(Byte.valueOf(GRBL_PAUSE_COMMAND), mgc.sentBytes.get(3)); } @Test diff --git a/ugs-core/test/com/willwinder/universalgcodesender/firmware/grbl/GrblOverrideManagerTest.java b/ugs-core/test/com/willwinder/universalgcodesender/firmware/grbl/GrblOverrideManagerTest.java index 883aab6e40..29467c7238 100644 --- a/ugs-core/test/com/willwinder/universalgcodesender/firmware/grbl/GrblOverrideManagerTest.java +++ b/ugs-core/test/com/willwinder/universalgcodesender/firmware/grbl/GrblOverrideManagerTest.java @@ -2,8 +2,10 @@ import com.willwinder.universalgcodesender.Capabilities; import com.willwinder.universalgcodesender.CapabilitiesConstants; +import com.willwinder.universalgcodesender.GrblUtils; import com.willwinder.universalgcodesender.IController; import com.willwinder.universalgcodesender.communicator.ICommunicator; +import com.willwinder.universalgcodesender.listeners.ControllerListener; import com.willwinder.universalgcodesender.listeners.ControllerState; import com.willwinder.universalgcodesender.listeners.ControllerStatus; import com.willwinder.universalgcodesender.listeners.ControllerStatusBuilder; @@ -16,8 +18,12 @@ import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.Test; +import org.mockito.ArgumentCaptor; import static org.mockito.ArgumentMatchers.anyByte; +import static org.mockito.ArgumentMatchers.eq; +import org.mockito.Captor; import org.mockito.Mock; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -31,11 +37,16 @@ public class GrblOverrideManagerTest { private IController controller; @Mock private ICommunicator communicator; + + @Captor + private ArgumentCaptor controllerListenerCaptor; + private GrblOverrideManager overrideManager; @Before public void setUp() { MockitoAnnotations.initMocks(this); + doNothing().when(controller).addListener(controllerListenerCaptor.capture()); overrideManager = new GrblOverrideManager(controller, communicator, new MessageService()); } @@ -153,6 +164,49 @@ public void hasSettledShouldReturnTrueWhenOverridePercentReachesTarget() { assertTrue(overrideManager.hasSettled()); } + @Test + public void onStreamCanceledShouldResetOverrides() throws Exception { + mockControllerStatus(ControllerState.IDLE); + mockOverrideCapabilities(); + + ControllerListener controllerListener = controllerListenerCaptor.getValue(); + controllerListener.streamCanceled(); + + assertOverridesResetted(); + } + + @Test + public void onStreamCompleteShouldResetOverrides() throws Exception { + mockControllerStatus(ControllerState.IDLE); + mockOverrideCapabilities(); + + ControllerListener controllerListener = controllerListenerCaptor.getValue(); + controllerListener.streamComplete(); + + assertOverridesResetted(); + } + + @Test + public void onStreamStartedShouldResetOverrides() throws Exception { + mockControllerStatus(ControllerState.IDLE); + mockOverrideCapabilities(); + + ControllerListener controllerListener = controllerListenerCaptor.getValue(); + controllerListener.streamStarted(); + + assertOverridesResetted(); + } + + private void assertOverridesResetted() throws Exception { + verify(communicator, times(1)).sendByteImmediately(eq(getOverrideCommand(Overrides.CMD_RAPID_OVR_RESET))); + verify(communicator, times(1)).sendByteImmediately(eq(getOverrideCommand(Overrides.CMD_FEED_OVR_RESET))); + verify(communicator, times(1)).sendByteImmediately(eq(getOverrideCommand(Overrides.CMD_SPINDLE_OVR_RESET))); + } + + private byte getOverrideCommand(Overrides overrides) { + return GrblUtils.getOverrideForEnum(overrides, controller.getCapabilities()); + } + private void mockControllerStatus(ControllerState controllerState) { ControllerStatus controllerStatus = ControllerStatusBuilder.newInstance().setOverrides(new OverridePercents(100, 100, 100)).setState(controllerState).build(); when(controller.getControllerStatus()).thenReturn(controllerStatus);