Skip to content

Commit

Permalink
Add new command processor for filtering out empty gcode lines (#2187)
Browse files Browse the repository at this point in the history
  • Loading branch information
breiler committed Mar 30, 2023
1 parent 28c79aa commit 2219913
Show file tree
Hide file tree
Showing 18 changed files with 172 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
Copyright 2023 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 <http://www.gnu.org/licenses/>.
*/
package com.willwinder.universalgcodesender.gcode.processors;

import com.willwinder.universalgcodesender.gcode.GcodeState;
import com.willwinder.universalgcodesender.gcode.util.GcodeParserException;
import com.willwinder.universalgcodesender.i18n.Localization;
import org.apache.commons.lang3.StringUtils;

import java.util.Collections;
import java.util.List;

/**
* Removes empty lines from the gcode file
*
* @author Joacim Breiler
*/
public class EmptyLineRemoverProcessor implements CommandProcessor {

@Override
public List<String> processCommand(String command, GcodeState state) throws GcodeParserException {
if (StringUtils.trimToNull(command) == null) {
return Collections.emptyList();
}
return Collections.singletonList(command);
}

@Override
public String getHelp() {
return Localization.getString("sender.help.empty-line-remover");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ private static CommandProcessor getProcessor(ProcessorConfig pc) {
return new SpindleOnDweller(duration);
case "LineSplitter":
return new LineSplitter(pc.args.get("segmentLengthMM").getAsDouble());
case "EmptyLineRemoverProcessor":
return new EmptyLineRemoverProcessor();
default:
throw new IllegalArgumentException("Unknown processor: " + pc.name);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -388,19 +388,14 @@ private static void preprocessAndWrite(GcodeParser gcp, IGcodeWriter gsw, String
LOGGER.log(Level.FINE, "gcode processing line: " + idx);
}

if (StringUtils.isEmpty(command)) {
gsw.addLine(command, command, comment, idx);
}
else {
// Parse the gcode for the buffer.
Collection<String> lines = gcp.preprocessCommand(command, gcp.getCurrentState());

for(String processedLine : lines) {
gsw.addLine(command, processedLine, comment, idx);
}
// Parse the gcode for the buffer.
Collection<String> lines = gcp.preprocessCommand(command, gcp.getCurrentState());

gcp.addCommand(command);
for(String processedLine : lines) {
gsw.addLine(command, processedLine, comment, idx);
}

gcp.addCommand(command);
}

/**
Expand Down
3 changes: 2 additions & 1 deletion ugs-core/src/resources/MessagesBundle_en_US.properties
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ platform.visualizer.boundary.invert.desc = On some controllers the machine max/m
platform.visualizer.autolevel.preview = Show auto leveler preview
platform.visualizer.autolevel.preview.desc = Shows the auto leveler preview
platform.visualizer.color.surface.high = Auto leveler high color
platform.visualizer.color.surface.low = Auto leveler low color
platform.visualizer.color.surface.low = Auto leveler low color

PendantMenu.item.StartServer = Start...
PendantMenu.item.StopServer = Stop...
Expand All @@ -363,6 +363,7 @@ parser.processor.arc.start-error = There is no starting point, unable to expand
parser.processor.arc.multiple-commands = Multiple commands were found on one line while expanding an arc, unable to continue. The command splitter processor can be used to continue.
sender.help.commandSplitter = Split gcode command into multiple parts for better error reporting.
sender.help.patternRemover = Removes text matching a regular expression pattern
sender.help.empty-line-remover = Removes empty lines from the gcode file
controller.exception.ignoreFutureErrors = Would you like to skip commands like this in the future?
settings.processors.header = Gcode Processor Configuration
settings.file.outOfDate.title = Out of date configuration
Expand Down
6 changes: 5 additions & 1 deletion ugs-core/src/resources/firmware_config/fluidnc.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Name": "FluidNC",
"Version": 1,
"Version": 2,
"Controller": {
"name": "FluidNC",
"args": null
Expand All @@ -11,6 +11,10 @@
"name": "CommentProcessor",
"enabled": true,
"optional": true
},{
"name": "EmptyLineRemoverProcessor",
"enabled": true,
"optional": true
},{
"name": "FeedOverrideProcessor",
"enabled": false,
Expand Down
6 changes: 5 additions & 1 deletion ugs-core/src/resources/firmware_config/g2core.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Name": "g2core",
"Version": 7,
"Version": 8,
"Controller": {
"name": "g2core",
"args": null
Expand All @@ -11,6 +11,10 @@
"name": "CommentProcessor",
"enabled": true,
"optional": true
},{
"name": "EmptyLineRemoverProcessor",
"enabled": true,
"optional": true
},{
"name": "FeedOverrideProcessor",
"enabled": false,
Expand Down
6 changes: 5 additions & 1 deletion ugs-core/src/resources/firmware_config/grbl.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Name": "GRBL",
"Version": 5,
"Version": 6,
"Controller": {
"name": "GRBL",
"args": null
Expand All @@ -11,6 +11,10 @@
"name": "CommentProcessor",
"enabled": true,
"optional": false
},{
"name": "EmptyLineRemoverProcessor",
"enabled": true,
"optional": true
},{
"name": "FeedOverrideProcessor",
"enabled": false,
Expand Down
6 changes: 5 additions & 1 deletion ugs-core/src/resources/firmware_config/grbl_esp32.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Name": "GRBL ESP32",
"Version": 5,
"Version": 6,
"Controller": {
"name": "GRBL ESP32",
"args": null
Expand All @@ -11,6 +11,10 @@
"name": "CommentProcessor",
"enabled": true,
"optional": false
},{
"name": "EmptyLineRemoverProcessor",
"enabled": true,
"optional": true
},{
"name": "FeedOverrideProcessor",
"enabled": false,
Expand Down
8 changes: 6 additions & 2 deletions ugs-core/src/resources/firmware_config/smoothieboard.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Name": "Smoothieware",
"Version": 6,
"Version": 7,
"Controller": {
"name": "SmoothieBoard",
"args": null
Expand All @@ -11,6 +11,10 @@
"name": "CommentProcessor",
"enabled": true,
"optional": false
},{
"name": "EmptyLineRemoverProcessor",
"enabled": true,
"optional": true
},{
"name": "FeedOverrideProcessor",
"enabled": false,
Expand Down Expand Up @@ -63,4 +67,4 @@
}
]
}
}
}
6 changes: 5 additions & 1 deletion ugs-core/src/resources/firmware_config/tinyg.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Name": "TinyG",
"Version": 5,
"Version": 6,
"Controller": {
"name": "TinyG",
"args": null
Expand All @@ -11,6 +11,10 @@
"name": "CommentProcessor",
"enabled": true,
"optional": false
},{
"name": "EmptyLineRemoverProcessor",
"enabled": true,
"optional": true
},{
"name": "FeedOverrideProcessor",
"enabled": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,27 @@ public void testRunFromFixtures() throws Exception {
});
}

@Test
public void testRemoveCommentsAndEmptyLinesFixtures() throws Exception {
runAllFixturesInPath("./gcode/fixtures/comments/", "EmptyLines", () -> {
GcodeParser gcp = new GcodeParser();
gcp.addCommandProcessor(new CommentProcessor());
gcp.addCommandProcessor(new EmptyLineRemoverProcessor());
gcp.addCommandProcessor(new LineSplitter(1));
return gcp;
});
}

@Test
public void testRemoveCommentsFixtures() throws Exception {
runAllFixturesInPath("./gcode/fixtures/comments/", "Comments", () -> {
GcodeParser gcp = new GcodeParser();
gcp.addCommandProcessor(new CommentProcessor());
gcp.addCommandProcessor(new LineSplitter(1));
return gcp;
});
}

private void runAllFixturesInPath(String basePath, String parserName, Callable<GcodeParser> initGcp) throws Exception {
List<String> resourceFiles = getResourceFiles(basePath);
System.out.printf("Running all fixtures in %s for %s:%n", basePath, parserName);
Expand All @@ -103,7 +124,6 @@ private void runAllFixturesInPath(String basePath, String parserName, Callable<G
}



public void runFixture(String basePath, String fixtureName, String parserName, GcodeParser gcp) throws Exception {
String inputFixture = basePath + fixtureName + ".input.nc";
String streamOutputFixture = basePath + "out" + parserName + "/" + fixtureName + ".stream_output.nc";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.willwinder.universalgcodesender.gcode.processors;

import com.willwinder.universalgcodesender.gcode.GcodeState;
import com.willwinder.universalgcodesender.gcode.util.GcodeParserException;
import org.junit.Test;

import java.util.List;

import static org.junit.Assert.assertEquals;

public class EmptyLineRemoverProcessorTest {
@Test
public void processCommandShouldNotRemoveEmptyLines() throws GcodeParserException {
EmptyLineRemoverProcessor processor = new EmptyLineRemoverProcessor();
List<String> lines = processor.processCommand("test", new GcodeState());
assertEquals(1, lines.size());
}

@Test
public void processCommandShouldRemoveTrimmedEmptyLines() throws GcodeParserException {
EmptyLineRemoverProcessor processor = new EmptyLineRemoverProcessor();
List<String> lines = processor.processCommand("", new GcodeState());
assertEquals(0, lines.size());

lines = processor.processCommand(" ", new GcodeState());
assertEquals(0, lines.size());

lines = processor.processCommand(" ", new GcodeState());
assertEquals(0, lines.size());

lines = processor.processCommand("\t", new GcodeState());
assertEquals(0, lines.size());

lines = processor.processCommand(null, new GcodeState());
assertEquals(0, lines.size());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
; Empty command with comment
(Another empty command with comment)

G0 ; Command with comment
G1 (Another command with comment)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@



G0
G1
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
gsw_meta:5
; Empty command with comment¶¶¶¶1¶¶Empty command with comment
(Another empty command with comment)¶¶¶¶2¶¶Another empty command with comment
¶¶¶¶3¶¶
G0 ; Command with comment¶¶G0¶¶4¶¶Command with comment
G1 (Another command with comment)¶¶G1¶¶5¶¶Another command with comment
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
G0
G1
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
gsw_meta:2
G0 ; Command with comment¶¶G0¶¶4¶¶Command with comment
G1 (Another command with comment)¶¶G1¶¶5¶¶Another command with comment
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ This file is part of Universal Gcode Sender (UGS).
import com.willwinder.universalgcodesender.model.events.ControllerStateEvent;
import com.willwinder.universalgcodesender.model.events.SettingChangedEvent;
import com.willwinder.universalgcodesender.utils.FirmwareUtils;
import com.willwinder.universalgcodesender.utils.ThreadHelper;
import static com.willwinder.universalgcodesender.utils.GUIHelpers.displayErrorDialog;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
Expand All @@ -35,8 +36,6 @@ This file is part of Universal Gcode Sender (UGS).
import org.openide.util.ImageUtilities;

import java.awt.*;
import static javax.swing.Action.NAME;
import static javax.swing.Action.SMALL_ICON;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
Expand Down Expand Up @@ -98,8 +97,9 @@ public Component getToolbarPresenter() {
panel.add(firmwareCombo);
c = panel;

// Baud rate options.
loadFirmwareSelector();
// Load firmware configuration in its own thread to make sure that
// the splash screen is not covering any firmware upgrade dialogs
ThreadHelper.invokeLater(this::loadFirmwareSelector);

firmwareCombo.addActionListener(a -> setFirmware());
}
Expand Down

0 comments on commit 2219913

Please sign in to comment.