ability to turn of line splitting for test

This commit is contained in:
Lars Brubaker 2018-10-09 14:29:51 -07:00
parent 67d7679a57
commit 385cf2288b
7 changed files with 147 additions and 119 deletions

View file

@ -65,48 +65,46 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
if (LineIndex < GCodeFile.LineCount)
{
if (LineIndex > 1
&& GCodeFile is GCodeMemoryFile currentMemoryFile)
&& GCodeFile is GCodeMemoryFile currentMemoryFile
&& switchToGCode != null)
{
if (switchToGCode != null)
var prevlayerIndex = currentMemoryFile.GetLayerIndex(LineIndex - 1);
var layerIndex = currentMemoryFile.GetLayerIndex(LineIndex);
// we only try to switch as we are changing layers
if (prevlayerIndex < layerIndex)
{
var prevlayerIndex = currentMemoryFile.GetLayerIndex(LineIndex - 1);
var layerIndex = currentMemoryFile.GetLayerIndex(LineIndex);
// we only try to switch as we are changing layers
if (prevlayerIndex < layerIndex)
var currentBottom = currentMemoryFile.GetLayerBottom(layerIndex);
// see if there is a layer height that is compatible in the new gcode
for (int i = 0; i < switchToGCode.LayerCount; i++)
{
var currentBottom = currentMemoryFile.GetLayerBottom(layerIndex);
// see if there is a layer height that is compatible in the new gcode
for (int i = 0; i < switchToGCode.LayerCount; i++)
// find the first layer in the new code that is greater than or eaqual to our current height
var switchBottom = switchToGCode.GetLayerBottom(i);
if (switchBottom >= currentBottom)
{
// find the first layer in the new code that is greater than or eaqual to our current height
var switchBottom = switchToGCode.GetLayerBottom(i);
if (switchBottom >= currentBottom)
// is the current gcode the same or bigger than the new gcode
if (currentBottom >= switchBottom)
{
// is the current gcode the same or bigger than the new gcode
if (currentBottom >= switchBottom)
// switch the first time we can
GCodeFile = switchToGCode;
LineIndex = switchToGCode.GetFirstLayerInstruction(i);
var line = $"G92 E{switchToGCode.Instruction(LineIndex).EPosition:0.###}";
switchToGCode = null;
return line;
}
else // only switch if we are within one layer height of the new gcode
{
if (currentBottom - switchBottom < switchToGCode.GetLayerHeight(layerIndex))
{
// switch the first time we can
GCodeFile = switchToGCode;
LineIndex = switchToGCode.GetFirstLayerInstruction(i);
var line = $"G92 E{switchToGCode.Instruction(LineIndex).EPosition}";
switchToGCode = null;
var line = $"G92 E{switchToGCode.Instruction(LineIndex).EPosition:0.###}";
switchToGCode = null;
return line;
}
else // only switch if we are within one layer height of the new gcode
{
if(currentBottom - switchBottom < switchToGCode.GetLayerHeight(layerIndex))
{
GCodeFile = switchToGCode;
LineIndex = switchToGCode.GetFirstLayerInstruction(i);
switchToGCode = null;
var line = $"G92 E{switchToGCode.Instruction(LineIndex).EPosition}";
switchToGCode = null;
return line;
}
}
// we are done evaluating after the first found layer
break;
}
// we are done evaluating after the first found layer
break;
}
}
}

View file

@ -27,97 +27,26 @@ of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using MatterHackers.VectorMath;
using System;
using System.Collections.Generic;
namespace MatterHackers.MatterControl.PrinterCommunication.Io
{
public class MaxLengthStream : GCodeStreamProxy
{
protected PrinterMove lastDestination = new PrinterMove();
private List<PrinterMove> movesToSend = new List<PrinterMove>();
private double maxSecondsPerSegment = 1.0/20.0; // 20 instruction per second
public class MaxLengthStream : GCodeStreamProxy
{
protected PrinterMove lastDestination = new PrinterMove();
// 20 instruction per second
private double maxSecondsPerSegment = 1.0 / 20.0;
private List<PrinterMove> movesToSend = new List<PrinterMove>();
public MaxLengthStream(GCodeStream internalStream, double maxSegmentLength)
: base(internalStream)
{
this.MaxSegmentLength = maxSegmentLength;
}
public MaxLengthStream(GCodeStream internalStream, double maxSegmentLength)
: base(internalStream)
{
this.MaxSegmentLength = maxSegmentLength;
}
public PrinterMove LastDestination { get { return lastDestination; } }
public double MaxSegmentLength { get; set; }
public override string ReadLine()
{
if (movesToSend.Count == 0)
{
string lineFromChild = base.ReadLine();
if (lineFromChild != null
&& LineIsMovement(lineFromChild))
{
PrinterMove currentDestination = GetPosition(lineFromChild, lastDestination);
PrinterMove deltaToDestination = currentDestination - lastDestination;
deltaToDestination.feedRate = 0; // remove the changing of the federate (we'll set it initially)
double lengthSquared = Math.Max(deltaToDestination.LengthSquared, deltaToDestination.extrusion * deltaToDestination.extrusion);
if (lengthSquared > MaxSegmentLength * MaxSegmentLength)
{
// create the line segments to send
double length = Math.Sqrt(lengthSquared);
int numSegmentsToCutInto = (int)Math.Ceiling(length / MaxSegmentLength);
// segments = (((mm/min) / (60s/min))mm/s / s/segment)segments*mm / mm
double maxSegmentsCanTransmit = 1 / (((currentDestination.feedRate / 60) * maxSecondsPerSegment) / length);
int numSegmentsToSend = Math.Max(1, Math.Min(numSegmentsToCutInto, (int)maxSegmentsCanTransmit));
if (numSegmentsToSend > 1)
{
PrinterMove deltaForSegment = deltaToDestination / numSegmentsToSend;
PrinterMove nextPoint = lastDestination + deltaForSegment;
nextPoint.feedRate = currentDestination.feedRate;
for (int i = 0; i < numSegmentsToSend; i++)
{
lock (movesToSend)
{
movesToSend.Add(nextPoint);
}
nextPoint += deltaForSegment;
}
// send the first one
PrinterMove positionToSend = movesToSend[0];
lock (movesToSend)
{
movesToSend.RemoveAt(0);
}
string altredLineToSend = CreateMovementLine(positionToSend, lastDestination);
lastDestination = positionToSend;
return altredLineToSend;
}
}
lastDestination = currentDestination;
}
return lineFromChild;
}
else
{
PrinterMove positionToSend = movesToSend[0];
lock (movesToSend)
{
movesToSend.RemoveAt(0);
}
string lineToSend = CreateMovementLine(positionToSend, lastDestination);
lastDestination = positionToSend;
return lineToSend;
}
}
public PrinterMove LastDestination { get { return lastDestination; } }
public double MaxSegmentLength { get; set; }
public void Cancel()
{
@ -127,8 +56,79 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
}
}
public override void SetPrinterPosition(PrinterMove position)
{
public override string ReadLine()
{
if (movesToSend.Count == 0)
{
string lineFromChild = base.ReadLine();
if (lineFromChild != null
&& LineIsMovement(lineFromChild))
{
PrinterMove currentDestination = GetPosition(lineFromChild, lastDestination);
PrinterMove deltaToDestination = currentDestination - lastDestination;
deltaToDestination.feedRate = 0; // remove the changing of the federate (we'll set it initially)
double lengthSquared = Math.Max(deltaToDestination.LengthSquared, deltaToDestination.extrusion * deltaToDestination.extrusion);
if (lengthSquared > MaxSegmentLength * MaxSegmentLength)
{
// create the line segments to send
double length = Math.Sqrt(lengthSquared);
int numSegmentsToCutInto = (int)Math.Ceiling(length / MaxSegmentLength);
// segments = (((mm/min) / (60s/min))mm/s / s/segment)segments*mm / mm
double maxSegmentsCanTransmit = 1 / (((currentDestination.feedRate / 60) * maxSecondsPerSegment) / length);
int numSegmentsToSend = Math.Max(1, Math.Min(numSegmentsToCutInto, (int)maxSegmentsCanTransmit));
if (numSegmentsToSend > 1)
{
PrinterMove deltaForSegment = deltaToDestination / numSegmentsToSend;
PrinterMove nextPoint = lastDestination + deltaForSegment;
nextPoint.feedRate = currentDestination.feedRate;
for (int i = 0; i < numSegmentsToSend; i++)
{
lock (movesToSend)
{
movesToSend.Add(nextPoint);
}
nextPoint += deltaForSegment;
}
// send the first one
PrinterMove positionToSend = movesToSend[0];
lock (movesToSend)
{
movesToSend.RemoveAt(0);
}
string altredLineToSend = CreateMovementLine(positionToSend, lastDestination);
lastDestination = positionToSend;
return altredLineToSend;
}
}
lastDestination = currentDestination;
}
return lineFromChild;
}
else
{
PrinterMove positionToSend = movesToSend[0];
lock (movesToSend)
{
movesToSend.RemoveAt(0);
}
string lineToSend = CreateMovementLine(positionToSend, lastDestination);
lastDestination = positionToSend;
return lineToSend;
}
}
public override void SetPrinterPosition(PrinterMove position)
{
lastDestination = position;
internalStream.SetPrinterPosition(lastDestination);
}

View file

@ -42,6 +42,7 @@ using MatterHackers.Agg;
using MatterHackers.Agg.UI;
using MatterHackers.MatterControl.DataStorage;
using MatterHackers.MatterControl.PrinterCommunication.Io;
using MatterHackers.MatterControl.SlicerConfiguration;
using MatterHackers.SerialPortCommunication;
using MatterHackers.SerialPortCommunication.FrostedSerial;
using MatterHackers.VectorMath;
@ -2128,7 +2129,8 @@ namespace MatterHackers.MatterControl.PrinterCommunication
queuedCommandStream3 = new QueuedCommandsStream(firstStreamToRead);
macroProcessingStream4 = new MacroProcessingStream(queuedCommandStream3, printer);
relativeToAbsoluteStream5 = new RelativeToAbsoluteStream(macroProcessingStream4);
babyStepsStream6 = new BabyStepsStream(printer.Settings, relativeToAbsoluteStream5, gcodeFilename == null ? 2000 : 1);
bool enableLineSpliting = gcodeFilename != null && printer.Settings.GetValue<bool>(SettingsKey.enable_line_spliting);
babyStepsStream6 = new BabyStepsStream(printer.Settings, relativeToAbsoluteStream5, enableLineSpliting ? 1 : 2000);
if (activePrintTask != null)
{
// make sure we are in the position we were when we stopped printing

View file

@ -64,6 +64,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
public const string default_material_presets = nameof(default_material_presets);
public const string device_token = nameof(device_token);
public const string device_type = nameof(device_type);
public const string enable_line_spliting = nameof(enable_line_spliting);
public const string enable_network_printing = nameof(enable_network_printing);
public const string enable_retractions = nameof(enable_retractions);
public const string enable_sailfish_communication = nameof(enable_sailfish_communication);

View file

@ -107,6 +107,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
SettingsKey.make,
SettingsKey.model,
SettingsKey.enable_network_printing,
SettingsKey.enable_line_spliting,
SettingsKey.enable_sailfish_communication,
SettingsKey.print_time_estimate_multiplier,
SettingsKey.ip_address,

View file

@ -1853,6 +1853,15 @@
"RebuildGCodeOnChange": false,
"ReloadUiWhenChanged": true
},
{
"SlicerConfigName": "enable_line_spliting",
"PresentationName": "Enable Line Spliting",
"HelpText": "Allow MatterControl to split long lines to improve levesing and print canceling. Critical for printers that are significantly out of level.",
"ShowIfSet": "!sla_printer",
"DataEditType": "CHECK_BOX",
"DefaultValue": "1",
"RebuildGCodeOnChange": false
},
{
"SlicerConfigName": "enable_sailfish_communication",
"PresentationName": "Sailfish Communication",

View file

@ -35,6 +35,7 @@ using System.Threading.Tasks;
using MatterHackers.Agg.UI;
using MatterHackers.GuiAutomation;
using MatterHackers.MatterControl.PartPreviewWindow;
using MatterHackers.MatterControl.SlicerConfiguration;
using MatterHackers.MatterControl.VersionManagement;
using NUnit.Framework;
@ -43,15 +44,20 @@ namespace MatterHackers.MatterControl.Tests.Automation
[TestFixture, Category("MatterControl.UI.Automation"), RunInApplicationDomain, Apartment(ApartmentState.STA)]
public class ReSliceTests
{
[Test, Category("Emulator")]
[Test, Category("Emulator"), Ignore("WIP")]
//[Test, Category("Emulator")]
public async Task ReSliceHasCorrectEPositions()
{
await MatterControlUtilities.RunTest((testRunner) =>
{
AutomationRunner.TimeToMoveMouse = .1;
//testRunner.ClickByName("Connection Wizard Skip Sign In Button");
using (var emulator = testRunner.LaunchAndConnectToPrinterEmulator())
{
var printer = ApplicationController.Instance.ActivePrinter;
printer.Settings.SetValue(SettingsKey.enable_line_spliting, "0");
var view3D = testRunner.GetWidgetByName("View3DWidget", out _) as View3DWidget;
var scene = view3D.InteractionLayer.Scene;
@ -65,9 +71,15 @@ namespace MatterHackers.MatterControl.Tests.Automation
// distance greater than the largest distance minus the max retraction
// amount and less than some amount that is reasonable
double lastAbsoluteEPostion = 0;
double largestRetraction = 0;
emulator.EPositionChanged += (e, s) =>
{
Assert.GreaterOrEqual(emulator.CurrentExtruder.AbsoluteEPosition, lastAbsoluteEPostion - 1, "We should never move back more than 1 mm");
var delta = emulator.CurrentExtruder.AbsoluteEPosition - lastAbsoluteEPostion;
if(delta < largestRetraction)
{
largestRetraction = delta;
}
Assert.GreaterOrEqual(-7, delta, "We should never move back more than 1 mm");
Assert.LessOrEqual(emulator.CurrentExtruder.AbsoluteEPosition, lastAbsoluteEPostion + 10, "We should never move up more than 10 mm");
lastAbsoluteEPostion = emulator.CurrentExtruder.AbsoluteEPosition;
};
@ -77,6 +89,8 @@ namespace MatterHackers.MatterControl.Tests.Automation
testRunner.ClickByName("Row Item cube_20x20x20");
testRunner.ClickByName("Print Library Overflow Menu");
testRunner.ClickByName("Add to Plate Menu Item");
testRunner.ClickByName("Print Library Overflow Menu");
testRunner.ClickByName("Add to Plate Menu Item");
// start the print
testRunner.StartPrint();
@ -134,6 +148,9 @@ namespace MatterHackers.MatterControl.Tests.Automation
// Wait for done
testRunner.WaitForPrintFinished();
// this will make sure we turned off line spliting and had good data about the extruder position
Assert.AreEqual(-7, largestRetraction, "Airwolf HD has a retraction of 7mm, make sure we had one");
}
return Task.CompletedTask;