Skip to content

Commit

Permalink
Update AutoLeveler to only warn when applying to gcode instead of on …
Browse files Browse the repository at this point in the history
…start

AutoLeveler apply to gcode will now remove old processors and replace instead of disabling button
Fixes for MeshLeveler relative mode (G91)
  • Loading branch information
lastacorn committed Oct 29, 2022
1 parent c55a40f commit eb10afa
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ public class MeshLeveler implements CommandProcessor {
final private int xLen, yLen;
final private double resolution;

// Used during processing.
private double lastZHeight;
private Units unit;

public final static String ERROR_MESH_SHAPE= "Surface mesh must be a rectangular 2D array.";
Expand All @@ -54,10 +52,10 @@ public class MeshLeveler implements CommandProcessor {
public final static String ERROR_X_ASCENTION = "Found a x coordinate that isn't ascending.";

public final static String ERROR_UNEXPECTED_ARC = "The mesh leveler cannot process arcs. Enable the arc expander.";
public final static String ERROR_MISSING_POINT_DATA = "Internal parser error: missing data.";
public final static String ERROR_MISSING_POINT_DATA = "Internal parser error: missing data. ";

/**
* @param materialSurfaceHeight Z height used in offset.
* @param materialSurfaceHeightMM Z height used in offset.
* @param surfaceMesh 2D array in the format Position[x][y]
*/
public MeshLeveler(double materialSurfaceHeightMM, Position[][] surfaceMesh, Units unit) {
Expand Down Expand Up @@ -155,17 +153,23 @@ public List<String> processCommand(final String commandString, GcodeState state)

GcodeMeta command = commands.get(0);

if (command == null || command.point == null) {
throw new GcodeParserException(ERROR_MISSING_POINT_DATA);
if (command == null) {
throw new GcodeParserException(ERROR_MISSING_POINT_DATA + commandString);
}
if (command.point == null) {
return Collections.singletonList(commandString);
}

// If we're in relative mode there is no adjustment needed
// TODO: This won't be true if we start in relative mode, in which case we need to ensure the first command
// is to move down by the offset at (0, 0)
if (!state.inAbsoluteMode) {
return Collections.singletonList(commandString);
}

Position start = state.currentPoint;
Position end = command.point.point();

if (start.z != end.z) {
this.lastZHeight = end.z;
}

// Get offset relative to the expected surface height.
// Visualizer normalizes everything to MM but probe mesh might be INCH
double probeScaleFactor = UnitUtils.scaleUnits(UnitUtils.Units.MM, this.unit);
Expand All @@ -177,7 +181,7 @@ public List<String> processCommand(final String commandString, GcodeState state)


// Update z coordinate.
end.z = this.lastZHeight + zPointOffset;
end.z += zPointOffset;
//end.z /= resultScaleFactor;

String adjustedCommand = GcodePreprocessorUtils.generateLineFromPoints(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ public void applyGcodeParser(GcodeParser parser) throws Exception {

@Override
public void applyCommandProcessor(CommandProcessor commandProcessor) throws Exception {
logger.log(Level.INFO, "Applying new command processor");
logger.log(Level.INFO, String.format("Applying new command processor %s", commandProcessor.getClass().getSimpleName()));
gcp.addCommandProcessor(commandProcessor);

if (gcodeFile != null) {
Expand All @@ -489,13 +489,13 @@ public File getGcodeFile() {

@Override
public File getProcessedGcodeFile() {
logger.log(Level.INFO, "Getting processed gcode file.");
logger.log(Level.INFO, String.format("Getting processed gcode file (%s).", this.processedGcodeFile));
return this.processedGcodeFile;
}

@Override
public void send() throws Exception {
logger.log(Level.INFO, "Sending gcode file.");
logger.log(Level.INFO, String.format("Sending gcode file (%s).", this.processedGcodeFile));
// Note: there is a divide by zero error in the timer because it uses
// the rowsValueLabel that was just reset.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ This file is part of Universal Gcode Sender (UGS).
*/
package com.willwinder.ugs.platform.surfacescanner;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.willwinder.ugs.nbm.visualizer.shared.RenderableUtils;
import com.willwinder.ugs.nbp.lib.lookup.CentralLookup;
import com.willwinder.ugs.nbp.lib.services.LocalizingService;
import com.willwinder.ugs.nbp.lib.services.TopComponentLocalizer;
import com.willwinder.universalgcodesender.gcode.GcodeParser;
import com.willwinder.universalgcodesender.gcode.processors.ArcExpander;
import com.willwinder.universalgcodesender.gcode.processors.CommentProcessor;
import com.willwinder.universalgcodesender.gcode.processors.CommandProcessor;
import com.willwinder.universalgcodesender.gcode.processors.LineSplitter;
import com.willwinder.universalgcodesender.gcode.processors.MeshLeveler;
import com.willwinder.universalgcodesender.i18n.Localization;
Expand Down Expand Up @@ -93,6 +93,8 @@ public final class AutoLevelerTopComponent extends TopComponent implements ItemL
public final static String AutoLevelerActionId = "com.willwinder.ugs.platform.surfacescanner.AutoLevelerTopComponent";
public final static String AutoLevelerCategory = LocalizingService.CATEGORY_WINDOW;

private ImmutableList<CommandProcessor> activeCommandProcessors = ImmutableList.of();

@OnStart
public static class Localizer extends TopComponentLocalizer {
public Localizer() {
Expand All @@ -119,6 +121,7 @@ public AutoLevelerTopComponent() {
yMax.addChangeListener(cl);
zMin.addChangeListener(cl);
zMax.addChangeListener(cl);
zSurface.addChangeListener(cl);
unitInch.addItemListener(this);
unitMM.addItemListener(this);

Expand Down Expand Up @@ -163,8 +166,8 @@ private void updateSettings() {
public void UGSEvent(UGSEvent evt) {
if (evt instanceof ProbeEvent) {
if (!scanner.isCollectedAllProbe()) return;
Position probe = ((ProbeEvent)evt).getProbePosition();

Position probe = ((ProbeEvent) evt).getProbePosition();
Position offset = this.settings.getAutoLevelSettings().autoLevelProbeOffset;

if (probe.getUnits() == Units.UNKNOWN || offset.getUnits() == Units.UNKNOWN) {
Expand All @@ -178,13 +181,9 @@ public void UGSEvent(UGSEvent evt) {
probe.y + offset.y,
probe.z + offset.z,
probe.getUnits()));
}

else if(evt instanceof SettingChangedEvent) {
} else if (evt instanceof SettingChangedEvent) {
updateSettings();
}

else if(evt instanceof FileStateEvent){
} else if (evt instanceof FileStateEvent) {
applyToGcode.setEnabled(true);
}
}
Expand All @@ -193,7 +192,7 @@ private double getValue(JSpinner spinner) {
Object o = spinner.getValue();
try {
return Double.parseDouble(o.toString());
} catch(Exception ignored) {
} catch (Exception ignored) {
}
return 0.0f;
}
Expand Down Expand Up @@ -225,7 +224,8 @@ private AutoLevelSettings updateScanner(Units units) {

/**
* JRadioButton's have strange state changes, so using item change.
* @param e
*
* @param e
*/
@Override
public void itemStateChanged(ItemEvent e) {
Expand Down Expand Up @@ -563,20 +563,20 @@ private void scanSurfaceButtonActionPerformed(java.awt.event.ActionEvent evt) {/

try {
scanner.enableCollectProbe(backend.getWorkPosition(), backend.getMachinePosition());

AutoLevelSettings als = settings.getAutoLevelSettings();
for (Position p : scanner.getProbeStartPositions()) {
backend.sendGcodeCommand(true, String.format("G90 G2%d G0 X%f Y%f Z%f",(p.getUnits() == Units.MM)? 1:0, p.x, p.y, p.z));
backend.sendGcodeCommand(true, String.format("G90 G2%d G0 X%f Y%f Z%f", (p.getUnits() == Units.MM) ? 1 : 0, p.x, p.y, p.z));
backend.probe("Z", als.probeSpeed, this.scanner.getProbeDistance(), u);
backend.sendGcodeCommand(true, String.format("G90 G2%d G0 Z%f",(p.getUnits() == Units.MM)? 1:0, p.z));
backend.sendGcodeCommand(true, String.format("G90 G2%d G0 Z%f", (p.getUnits() == Units.MM) ? 1 : 0, p.z));
}
} catch (Exception ex) {
Exceptions.printStackTrace(ex);
}
}//GEN-LAST:event_scanSurfaceButtonActionPerformed

private void dataViewerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dataViewerActionPerformed
List<Map<String,Double>> probeData = new ArrayList<>();
List<Map<String, Double>> probeData = new ArrayList<>();

// Collect data from grid.
if (scanner != null && scanner.getProbePositionGrid() != null) {
Expand All @@ -599,26 +599,32 @@ private void dataViewerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FI
}//GEN-LAST:event_dataViewerActionPerformed

private void applyToGcodeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_applyToGcodeActionPerformed
GcodeParser gcp = new GcodeParser();
Settings.AutoLevelSettings autoLevelSettings = this.settings.getAutoLevelSettings();

// Step 0: Get rid of comments.
gcp.addCommandProcessor(new CommentProcessor());

// Step 1: The arc processor and line processors NO LONGER need to be split!
ImmutableList.Builder<CommandProcessor> commandProcessors = ImmutableList.builder();
try {
for(CommandProcessor p : activeCommandProcessors) {
backend.removeCommandProcessor(p);
}

// Step 2: Must convert arcs to line segments.
gcp.addCommandProcessor(new ArcExpander(true, autoLevelSettings.autoLevelArcSliceLength));
// Step 1: Convert arcs to line segments.
commandProcessors.add(new ArcExpander(true, autoLevelSettings.autoLevelArcSliceLength));

// Step 3: Line splitter. No line should be longer than some fraction of "resolution"
gcp.addCommandProcessor(new LineSplitter(getValue(stepResolution)/10));
// Step 2: Line splitter. No line should be longer than some fraction of "resolution"
commandProcessors.add(new LineSplitter(getValue(stepResolution) / 10));

// Step 4: Adjust Z heights codes based on mesh offsets.
gcp.addCommandProcessor(new MeshLeveler(getValue(this.zSurface), scanner.getProbePositionGrid(), scanner.getUnits()));
// Step 3: Adjust Z heights codes based on mesh offsets.
commandProcessors.add(
new MeshLeveler(getValue(this.zSurface),
scanner.getProbePositionGrid(),
scanner.getUnits()));

try {
backend.applyGcodeParser(gcp);
applyToGcode.setEnabled(false);
activeCommandProcessors = commandProcessors.build();
for(CommandProcessor p : activeCommandProcessors) {
backend.applyCommandProcessor(p);
}
GUIHelpers.displayHelpDialog(
"The autoleveler feature is under development and may not work properly, use at your own risk.");
} catch (Exception ex) {
GUIHelpers.displayErrorDialog(ex.getMessage());
Exceptions.printStackTrace(ex);
Expand Down Expand Up @@ -650,11 +656,11 @@ private void useLoadedFileActionPerformed(java.awt.event.ActionEvent evt) {//GEN
}//GEN-LAST:event_useLoadedFileActionPerformed

private void generateTestDataButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_generateTestDataButtonActionPerformed
if(scanner.getProbeStartPositions() == null)
if (scanner.getProbeStartPositions() == null)
return;

scanner.enableTestProbe();

// Generate some random test data.
Random random = new Random();

Expand Down Expand Up @@ -702,7 +708,6 @@ private void visibleAutoLevelerActionPerformed(java.awt.event.ActionEvent evt) {

@Override
public void componentOpened() {
GUIHelpers.displayHelpDialog("The autoleveler feature currently doesn't work properly, close the autoleveler window to disable this message in the future.");
scanner = new SurfaceScanner();
if (r == null) {
r = new AutoLevelPreview(Localization.getString("platform.visualizer.renderable.autolevel-preview"));
Expand All @@ -718,10 +723,10 @@ public void componentClosed() {
}

public void writeProperties(java.util.Properties p) {
// No properties
// No properties
}

public void readProperties(java.util.Properties p) {
// No properties
// No properties
}
}

0 comments on commit eb10afa

Please sign in to comment.