Merge pull request #2029 from larsbrubaker/1.7

Added ability to sample multiple times on same point.
This commit is contained in:
Lars Brubaker 2017-04-13 17:11:24 -07:00 committed by GitHub
commit 2e15844242
9 changed files with 169 additions and 68 deletions

View file

@ -36,6 +36,7 @@ using MatterHackers.MatterControl.SlicerConfiguration;
using MatterHackers.VectorMath;
using System;
using System.Collections.Generic;
using System.Linq;
namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
{
@ -335,12 +336,12 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
StringEventArgs currentEvent = e as StringEventArgs;
if (currentEvent != null)
{
double sampleRead = double.MinValue;
if (currentEvent.Data.StartsWith("Bed")) // marlin G30 return code (looks like: 'Bed Position X:20 Y:32 Z:.01')
{
probePositions[probePositionsBeingEditedIndex].position.x = probeStartPosition.x;
probePositions[probePositionsBeingEditedIndex].position.y = probeStartPosition.y;
GCodeFile.GetFirstNumberAfter("Z:", currentEvent.Data, ref probePositions[probePositionsBeingEditedIndex].position.z);
UiThread.RunOnIdle(() => container.nextButton.ClickButton(null));
GCodeFile.GetFirstNumberAfter("Z:", currentEvent.Data, ref sampleRead);
}
else if (currentEvent.Data.StartsWith("Z:")) // smoothie G30 return code (looks like: 'Z:10.01')
{
@ -349,8 +350,26 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
// smoothie returns the position relative to the start postion
double reportedProbeZ = 0;
GCodeFile.GetFirstNumberAfter("Z:", currentEvent.Data, ref reportedProbeZ);
probePositions[probePositionsBeingEditedIndex].position.z = reportedProbeZ - probeStartPosition.z;
UiThread.RunOnIdle(() => container.nextButton.ClickButton(null));
sampleRead = probeStartPosition.z - reportedProbeZ;
}
if (sampleRead != double.MinValue)
{
samples.Add(sampleRead);
if (samples.Count == NumberOfSamples)
{
samples.Sort();
if (samples.Count > 3)
{
// drop the high and low values
samples.RemoveAt(0);
samples.RemoveAt(samples.Count - 1);
}
probePositions[probePositionsBeingEditedIndex].position.z = Math.Round(samples.Average(), 2);
UiThread.RunOnIdle(() => container.nextButton.ClickButton(null));
}
}
}
}
@ -364,6 +383,9 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
base.OnClosed(e);
}
readonly int NumberOfSamples = 5;
List<double> samples = new List<double>();
public override void PageIsBecomingActive()
{
// always make sure we don't have print leveling turned on
@ -375,7 +397,10 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
PrinterConnectionAndCommunication.Instance.MoveAbsolute(PrinterConnectionAndCommunication.Axis.Z, probeStartPosition.z, feedRates.z);
PrinterConnectionAndCommunication.Instance.MoveAbsolute(probeStartPosition, feedRates.x);
PrinterConnectionAndCommunication.Instance.SendLineToPrinterNow("G30"); // probe the current position
for (int i = 0; i < NumberOfSamples; i++)
{
PrinterConnectionAndCommunication.Instance.SendLineToPrinterNow("G30"); // probe the current position
}
container.backButton.Enabled = false;
container.nextButton.Enabled = false;

View file

@ -28,34 +28,32 @@ either expressed or implied, of the FreeBSD Project.
*/
using MatterHackers.Agg;
using MatterHackers.GCodeVisualizer;
using MatterHackers.MatterControl.SlicerConfiguration;
using MatterHackers.VectorMath;
using System.Collections.Generic;
using System;
using MatterHackers.MatterControl.SlicerConfiguration;
using System.Diagnostics;
using System.Linq;
using MatterHackers.GCodeVisualizer;
namespace MatterHackers.MatterControl.PrinterCommunication.Io
{
public class PauseHandlingStream : GCodeStreamProxy
{
object locker = new object();
private List<string> commandQueue = new List<string>();
protected PrinterMove lastDestination = new PrinterMove();
public PrinterMove LastDestination { get { return lastDestination; } }
PrinterMove moveLocationAtEndOfPauseCode;
public override void SetPrinterPosition(PrinterMove position)
{
lastDestination = position;
internalStream.SetPrinterPosition(lastDestination);
}
private List<string> commandQueue = new List<string>();
private object locker = new object();
private PrinterMove moveLocationAtEndOfPauseCode;
private Stopwatch timeSinceLastEndstopRead = new Stopwatch();
public PauseHandlingStream(GCodeStream internalStream)
: base(internalStream)
{
}
public enum PauseReason { UserRequested, PauseLayerReached, GCodeRequest, FillamentRunout }
public PrinterMove LastDestination { get { return lastDestination; } }
public void Add(string line)
{
// lock queue
@ -65,37 +63,25 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
}
}
private void InjectPauseGCode(string codeToInject)
public void DoPause(PauseReason pauseReason)
{
codeToInject = GCodeProcessing.ReplaceMacroValues(codeToInject);
codeToInject = codeToInject.Replace("\\n", "\n");
string[] lines = codeToInject.Split('\n');
for (int i = 0; i < lines.Length; i++)
var pcc = PrinterConnectionAndCommunication.Instance;
switch (pauseReason)
{
string[] splitOnSemicolon = lines[i].Split(';');
string trimedLine = splitOnSemicolon[0].Trim().ToUpper();
if (trimedLine != "")
{
this.Add(trimedLine);
}
case PauseReason.UserRequested:
// do nothing special
break;
case PauseReason.PauseLayerReached:
case PauseReason.GCodeRequest:
pcc.PauseOnLayer.CallEvents(pcc, new PrintItemWrapperEventArgs(pcc.ActivePrintItem));
break;
case PauseReason.FillamentRunout:
pcc.FillamentRunout.CallEvents(pcc, new PrintItemWrapperEventArgs(pcc.ActivePrintItem));
break;
}
}
private bool PauseOnLayer(string layer)
{
int layerNumber;
if (int.TryParse(layer, out layerNumber) && ActiveSliceSettings.Instance.Helpers.LayerToPauseOn().Contains(layerNumber))
{
return true;
}
return false;
}
public void DoPause()
{
// Add the pause_gcode to the loadedGCode.GCodeCommandQueue
string pauseGCode = ActiveSliceSettings.Instance.GetValue(SettingsKey.pause_gcode);
@ -108,21 +94,6 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
InjectPauseGCode("MH_PAUSE");
}
public void Resume()
{
// first go back to where we were after executing the pause code
Vector3 positionBeforeActualPause = moveLocationAtEndOfPauseCode.position;
InjectPauseGCode("G92 E{0:0.###}".FormatWith(moveLocationAtEndOfPauseCode.extrusion));
Vector3 ensureAllAxisAreSent = positionBeforeActualPause + new Vector3(.01, .01, .01);
var feedRates = ActiveSliceSettings.Instance.Helpers.ManualMovementSpeeds();
InjectPauseGCode("G1 X{0:0.###} Y{1:0.###} Z{2:0.###} F{3}".FormatWith(ensureAllAxisAreSent.x, ensureAllAxisAreSent.y, ensureAllAxisAreSent.z, feedRates.x + 1));
InjectPauseGCode("G1 X{0:0.###} Y{1:0.###} Z{2:0.###} F{3}".FormatWith(positionBeforeActualPause.x, positionBeforeActualPause.y, positionBeforeActualPause.z, feedRates));
string resumeGCode = ActiveSliceSettings.Instance.GetValue(SettingsKey.resume_gcode);
InjectPauseGCode(resumeGCode);
InjectPauseGCode("M114"); // make sure we know where we are after this resume code
}
public override string ReadLine()
{
string lineToSend = null;
@ -145,6 +116,17 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
{
return lineToSend;
}
// We got a line from the gcode we are sending check if we should queue a request for fillament runout
if (ActiveSliceSettings.Instance.GetValue(SettingsKey.fillament_runout_endstop) != "None")
{
// request to read the endstop state
if (!timeSinceLastEndstopRead.IsRunning || timeSinceLastEndstopRead.ElapsedMilliseconds > 5000)
{
PrinterConnectionAndCommunication.Instance.SendLineToPrinterNow("M119");
timeSinceLastEndstopRead.Restart();
}
}
}
else
{
@ -157,12 +139,18 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
string layerNumber = lineToSend.Split(':')[1];
if (PauseOnLayer(layerNumber))
{
DoPause();
DoPause(PauseReason.PauseLayerReached);
}
}
else if (lineToSend.StartsWith("M226") || lineToSend.StartsWith("@pause"))
else if (lineToSend.StartsWith("M226")
|| lineToSend.StartsWith("@pause"))
{
DoPause();
DoPause(PauseReason.GCodeRequest);
lineToSend = "";
}
else if (OutOfFillament())
{
DoPause(PauseReason.FillamentRunout);
lineToSend = "";
}
else if (lineToSend == "MH_PAUSE")
@ -187,5 +175,64 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
return lineToSend;
}
public void Resume()
{
// first go back to where we were after executing the pause code
Vector3 positionBeforeActualPause = moveLocationAtEndOfPauseCode.position;
InjectPauseGCode("G92 E{0:0.###}".FormatWith(moveLocationAtEndOfPauseCode.extrusion));
Vector3 ensureAllAxisAreSent = positionBeforeActualPause + new Vector3(.01, .01, .01);
var feedRates = ActiveSliceSettings.Instance.Helpers.ManualMovementSpeeds();
InjectPauseGCode("G1 X{0:0.###} Y{1:0.###} Z{2:0.###} F{3}".FormatWith(ensureAllAxisAreSent.x, ensureAllAxisAreSent.y, ensureAllAxisAreSent.z, feedRates.x + 1));
InjectPauseGCode("G1 X{0:0.###} Y{1:0.###} Z{2:0.###} F{3}".FormatWith(positionBeforeActualPause.x, positionBeforeActualPause.y, positionBeforeActualPause.z, feedRates));
string resumeGCode = ActiveSliceSettings.Instance.GetValue(SettingsKey.resume_gcode);
InjectPauseGCode(resumeGCode);
InjectPauseGCode("M114"); // make sure we know where we are after this resume code
}
public override void SetPrinterPosition(PrinterMove position)
{
lastDestination = position;
internalStream.SetPrinterPosition(lastDestination);
}
private void InjectPauseGCode(string codeToInject)
{
codeToInject = GCodeProcessing.ReplaceMacroValues(codeToInject);
codeToInject = codeToInject.Replace("\\n", "\n");
string[] lines = codeToInject.Split('\n');
for (int i = 0; i < lines.Length; i++)
{
string[] splitOnSemicolon = lines[i].Split(';');
string trimedLine = splitOnSemicolon[0].Trim().ToUpper();
if (trimedLine != "")
{
this.Add(trimedLine);
}
}
}
private bool OutOfFillament()
{
if (ActiveSliceSettings.Instance.GetValue(SettingsKey.fillament_runout_endstop) != "None")
{
}
return false;
}
private bool PauseOnLayer(string layer)
{
int layerNumber;
if (int.TryParse(layer, out layerNumber) && ActiveSliceSettings.Instance.Helpers.LayerToPauseOn().Contains(layerNumber))
{
return true;
}
return false;
}
}
}

View file

@ -107,6 +107,10 @@ namespace MatterHackers.MatterControl.PrinterCommunication
public RootedObjectEventHandler PrintFinished = new RootedObjectEventHandler();
public RootedObjectEventHandler PauseOnLayer = new RootedObjectEventHandler();
public RootedObjectEventHandler FillamentRunout = new RootedObjectEventHandler();
public RootedObjectEventHandler PrintingStateChanged = new RootedObjectEventHandler();
public RootedObjectEventHandler ReadLine = new RootedObjectEventHandler();
@ -289,6 +293,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
ReadLineContainsCallBacks.AddCallbackToKey("Heater decoupled", PrinterReportsError);
ReadLineContainsCallBacks.AddCallbackToKey("cold extrusion prevented", PrinterReportsError);
ReadLineContainsCallBacks.AddCallbackToKey("Error:Thermal Runaway, system stopped!", PrinterReportsError);
ReadLineContainsCallBacks.AddCallbackToKey("Error:Heating failed", PrinterReportsError);
// repetier temperature failures
ReadLineContainsCallBacks.AddCallbackToKey("dry run mode", PrinterReportsError);
@ -1869,7 +1874,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication
return;
}
pauseHandlingStream1.DoPause();
pauseHandlingStream1.DoPause(PauseHandlingStream.PauseReason.UserRequested);
}
}

View file

@ -74,6 +74,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
public const string filament_cost = nameof(filament_cost);
public const string filament_density = nameof(filament_density);
public const string filament_diameter = nameof(filament_diameter);
public const string fillament_runout_endstop = nameof(fillament_runout_endstop);
public const string fill_density = nameof(fill_density);
public const string fill_thin_gaps = nameof(fill_thin_gaps);
public const string first_layer_extrusion_width = nameof(first_layer_extrusion_width);
@ -106,6 +107,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
public const string print_leveling_enabled = nameof(print_leveling_enabled);
public const string print_leveling_probe_start = nameof(print_leveling_probe_start);
public const string print_leveling_required_to_print = nameof(print_leveling_required_to_print);
public const string print_leveling_solution = nameof(print_leveling_solution);
public const string printer_name = nameof(printer_name);
public const string publish_bed_image = nameof(publish_bed_image);
public const string recover_first_layer_speed = nameof(recover_first_layer_speed);

View file

@ -59,13 +59,13 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
SettingsKey.com_port,
SettingsKey.filament_cost,
SettingsKey.filament_density,
SettingsKey.fillament_runout_endstop,
SettingsKey.manual_probe_paper_width,
SettingsKey.use_g30_for_bed_probe,
SettingsKey.pause_gcode,
"print_leveling_method",
SettingsKey.print_leveling_probe_start,
SettingsKey.print_leveling_required_to_print,
"print_leveling_solution",
SettingsKey.print_leveling_solution,
SettingsKey.recover_first_layer_speed,
SettingsKey.recover_is_enabled,
SettingsKey.recover_position_before_z_home,

View file

@ -82,7 +82,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
"wipe_shield_distance",
SettingsKey.heat_extruder_before_homing,
"extruders_share_temperature",
"print_leveling_method",
"solid_shell",
"retractWhenChangingIslands",
SettingsKey.perimeter_start_end_overlap,

View file

@ -311,6 +311,7 @@ Advanced
has_power_control
enable_network_printing
enable_sailfish_communication
fillament_runout_endstop
Behavior
z_homes_to_max
z_can_be_negative
@ -325,7 +326,6 @@ Advanced
Print Leveling
Machine Settings
print_leveling_solution
print_leveling_method
print_leveling_required_to_print
Probe Settings
print_leveling_probe_start

View file

@ -1145,6 +1145,20 @@
"ReloadUiWhenChanged": true,
"RebuildGCodeOnChange": false
},
{
"QuickMenuSettings": [ ],
"SetSettingsOnChange": [ ],
"SlicerConfigName": "fillament_runout_endstop",
"PresentationName": "Fillament Runout Endstop",
"HelpText": "Specifies the endstop (if any) that is used to detect filament runout. Closed state defines filament has runout. If runout is detected the printers pause G-Code is run.",
"DataEditType": "LIST",
"ExtraSettings": "None,X Min,X Max,Y Min,Y Max,Z Min,Z Max",
"ShowAsOverride": true,
"ResetAtEndOfPrint": false,
"DefaultValue": "None",
"ReloadUiWhenChanged": true,
"RebuildGCodeOnChange": false
},
{
"QuickMenuSettings": [ ],
"SetSettingsOnChange": [ ],

View file

@ -6037,3 +6037,12 @@ Translated:Note: Be sure the tip of the extruder is clean and the bed is clear.
English:Use G30 For Probing
Translated:Use G30 For Probing
English:Specifies the endstop (if any) that is used to detect filament runout. Closed state defines filament has runout. If runout is detected the printers pause G-Code is run.
Translated:Specifies the endstop (if any) that is used to detect filament runout. Closed state defines filament has runout. If runout is detected the printers pause G-Code is run.
English:Fillament Runout Endstop
Translated:Fillament Runout Endstop
English:Home the printer
Translated:Home the printer