improving extruder switiching

This commit is contained in:
Lars Brubaker 2019-03-01 19:38:59 -08:00
parent 0a5b7eb7c8
commit 5997c5688b
8 changed files with 321 additions and 192 deletions

View file

@ -29,25 +29,75 @@ either expressed or implied, of the FreeBSD Project.
using System;
using System.Collections.Generic;
using System.Text;
using MatterControl.Printing;
using MatterHackers.Agg;
using MatterHackers.MatterControl.SlicerConfiguration;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.PrinterCommunication.Io
{
public class ToolChangeStream : GCodeStreamProxy
{
private Queue<string> commandQueue = new Queue<string>();
private object locker = new object();
private bool watingForBeforeGCode = false;
private int requestedExtruder;
private int activeExtruderIndex;
private int extruderIndex;
PrinterMove lastDestination = PrinterMove.Unknown;
private QueuedCommandsStream queuedCommandsStream;
int extruderCount = 0;
Vector3[] extruderOffsets = new Vector3[4];
private double preSwitchFeedRate;
private Vector3 preSwitchPosition;
private string postSwitchLine;
private readonly string compleatedBeforeGCodeString = "; COMPLEATED_BEFORE_GCODE";
public ToolChangeStream(PrinterConfig printer, GCodeStream internalStream)
public ToolChangeStream(PrinterConfig printer, GCodeStream internalStream, QueuedCommandsStream queuedCommandsStream)
: base(printer, internalStream)
{
this.queuedCommandsStream = queuedCommandsStream;
extruderCount = printer.Settings.GetValue<int>(SettingsKey.extruder_count);
activeExtruderIndex = printer.Connection.ActiveExtruderIndex;
extruderIndex = printer.Connection.ActiveExtruderIndex;
printer.Settings.SettingChanged += Settings_SettingChanged;
ReadExtruderOffsets();
}
private void Settings_SettingChanged(object sender, StringEventArgs stringEvent)
{
if (stringEvent != null)
{
// if the offsets change update them (unless we are actively printing)
if (stringEvent.Data == SettingsKey.extruder_offset
&& !printer.Connection.Printing
&& !printer.Connection.Paused)
{
ReadExtruderOffsets();
}
}
}
private void ReadExtruderOffsets()
{
for (int i = 0; i < 4; i++)
{
extruderOffsets[i] = printer.Settings.Helpers.ExtruderOffset(i);
}
}
public override void Dispose()
{
printer.Settings.SettingChanged -= Settings_SettingChanged;
base.Dispose();
}
public override void SetPrinterPosition(PrinterMove position)
{
this.lastDestination.CopyKnowSettings(position);
if (extruderIndex < 4)
{
lastDestination.position += extruderOffsets[extruderIndex];
}
internalStream.SetPrinterPosition(lastDestination);
}
public override string DebugInfo
@ -58,125 +108,148 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
}
}
private bool CheckIfNeedToSwitchExtruders(string lineIn)
private bool QueueBeforeIfNeedToSwitchExtruders(string lineIn)
{
bool queuedSwitch = false;
if (lineIn == null)
{
return queuedSwitch;
return false;
}
postSwitchLine = lineIn;
var lineNoComment = lineIn.Split(';')[0];
TrackExtruderState(lineNoComment);
bool queuedSwitch = false;
// check if there is a travel
if ((lineNoComment.StartsWith("G0 ") || lineNoComment.StartsWith("G1 ")) // is a G1 or G0
&& (lineNoComment.Contains("X") || lineNoComment.Contains("Y") || lineNoComment.Contains("Z")) // hase a move axis in it
&& activeExtruderIndex != requestedExtruder) // is different than the last extruder set
&& extruderIndex != requestedExtruder // is different than the last extruder set
&& !watingForBeforeGCode)
{
string beforeGcodeToQueue = "";
string afterGcodeToQueue = "";
switch (requestedExtruder)
{
case 0:
beforeGcodeToQueue = printer.Settings.GetValue(SettingsKey.before_toolchange_gcode).Replace("\\n", "\n");
afterGcodeToQueue = printer.Settings.GetValue(SettingsKey.toolchange_gcode).Replace("\\n", "\n");
break;
case 1:
beforeGcodeToQueue = printer.Settings.GetValue(SettingsKey.before_toolchange_gcode_1).Replace("\\n", "\n");
afterGcodeToQueue = printer.Settings.GetValue(SettingsKey.toolchange_gcode_1).Replace("\\n", "\n");
break;
}
var feedRate = lastDestination.feedRate;
var preSwitchPosition = lastDestination.position;
preSwitchFeedRate = lastDestination.feedRate;
preSwitchPosition = lastDestination.position;
// put together the output we want to send
var gcode = new StringBuilder();
if (beforeGcodeToQueue.Trim().Length > 0)
{
string[] linesToWrite = beforeGcodeToQueue.Split(new string[] { "\n" }, StringSplitOptions.None);
for (int i = 0; i < linesToWrite.Length; i++)
{
string gcodeLine = linesToWrite[i].Trim();
if (gcodeLine.Length > 0)
{
commandQueue.Enqueue(printer.ReplaceMacroValues(gcodeLine));
}
}
watingForBeforeGCode = true;
gcode.Append(printer.ReplaceMacroValues(beforeGcodeToQueue));
}
if (afterGcodeToQueue.Trim().Length > 0)
{
string[] linesToWrite = afterGcodeToQueue.Split(new string[] { "\n" }, StringSplitOptions.None);
for (int i = 0; i < linesToWrite.Length; i++)
{
string gcodeLine = linesToWrite[i].Trim();
if (gcodeLine.Length > 0)
{
commandQueue.Enqueue(printer.ReplaceMacroValues(gcodeLine));
}
}
}
// move to selected tool to the last tool position at the travel speed
if (preSwitchPosition.X != double.PositiveInfinity
&& preSwitchPosition.Y != double.PositiveInfinity)
{
commandQueue.Enqueue($"G1 X{preSwitchPosition.X}Y{preSwitchPosition.Y}F{printer.Settings.XSpeed()}");
}
// move to the z position
if (preSwitchPosition.Z != double.PositiveInfinity)
{
commandQueue.Enqueue($"G1 Z{preSwitchPosition.Z}F{printer.Settings.ZSpeed()}");
}
// set the feedrate back to what was before we added any code
if (feedRate != double.PositiveInfinity)
{
commandQueue.Enqueue($"G1 F{feedRate}");
}
// and queue the travel
commandQueue.Enqueue(lineIn);
gcode.AppendLine("\n" + compleatedBeforeGCodeString);
queuedCommandsStream.Add(gcode.ToString());
queuedSwitch = true;
activeExtruderIndex = requestedExtruder;
}
return queuedSwitch;
}
public override void SetPrinterPosition(PrinterMove position)
private void QueueAfterGCode()
{
this.lastDestination.CopyKnowSettings(position);
internalStream.SetPrinterPosition(lastDestination);
string afterGcodeToQueue = "";
switch (requestedExtruder)
{
case 0:
afterGcodeToQueue = printer.Settings.GetValue(SettingsKey.toolchange_gcode).Replace("\\n", "\n");
break;
case 1:
afterGcodeToQueue = printer.Settings.GetValue(SettingsKey.toolchange_gcode_1).Replace("\\n", "\n");
break;
}
// put together the output we want to send
var gcode = new StringBuilder();
if (afterGcodeToQueue.Trim().Length > 0)
{
gcode.Append(printer.ReplaceMacroValues(afterGcodeToQueue));
}
// move to selected tool to the last tool position at the travel speed
if (preSwitchPosition.X != double.PositiveInfinity
&& preSwitchPosition.Y != double.PositiveInfinity)
{
gcode.AppendLine($"\n G1 X{preSwitchPosition.X}Y{preSwitchPosition.Y}F{printer.Settings.XSpeed()}");
}
// move to the z position
if (preSwitchPosition.Z != double.PositiveInfinity)
{
gcode.AppendLine($"G1 Z{preSwitchPosition.Z}F{printer.Settings.ZSpeed()}");
}
// set the feedrate back to what was before we added any code
if (preSwitchFeedRate != double.PositiveInfinity)
{
gcode.AppendLine($"G1 F{preSwitchFeedRate}");
}
// and queue the travel
gcode.AppendLine(postSwitchLine);
queuedCommandsStream.Add(gcode.ToString());
}
public override string ReadLine()
{
string lineToSend = null;
string lineToSend = base.ReadLine();
// lock queue
lock (locker)
if (lineToSend != null
&& lineToSend.EndsWith("; NO_PROCESSING"))
{
if (commandQueue.Count > 0)
{
return commandQueue.Dequeue();
}
return lineToSend;
}
if (lineToSend == null)
if(lineToSend == compleatedBeforeGCodeString)
{
lineToSend = base.ReadLine();
extruderIndex = requestedExtruder;
watingForBeforeGCode = false;
QueueAfterGCode();
}
if(CheckIfNeedToSwitchExtruders(lineToSend))
if (QueueBeforeIfNeedToSwitchExtruders(lineToSend))
{
return "";
}
TrackExtruderState(lineToSend);
if (lineToSend != null
&& LineIsMovement(lineToSend))
{
PrinterMove currentMove = GetPosition(lineToSend, lastDestination);
PrinterMove moveToSend = currentMove;
if (extruderIndex < 4)
{
moveToSend.position -= extruderOffsets[extruderIndex];
}
if (moveToSend.HaveAnyPosition)
{
lineToSend = CreateMovementLine(moveToSend, lastDestination);
}
lastDestination = currentMove;
return lineToSend;
}
return lineToSend;
}
@ -189,7 +262,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
if (line.StartsWith("G28)"))
{
activeExtruderIndex = 0;
extruderIndex = 0;
requestedExtruder = 0;
}