2015-11-29 23:15:47 -08:00
/ *
2016-05-11 10:44:23 -07:00
Copyright ( c ) 2016 , Kevin Pope , Lars Brubaker , John Lewin
2015-11-29 23:15:47 -08:00
All rights reserved .
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions are met :
1. Redistributions of source code must retain the above copyright notice , this
list of conditions and the following disclaimer .
2. Redistributions in binary form must reproduce the above copyright notice ,
this list of conditions and the following disclaimer in the documentation
and / or other materials provided with the distribution .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies ,
either expressed or implied , of the FreeBSD Project .
* /
2016-09-20 09:39:57 -07:00
using System.Collections.Generic ;
2016-11-30 13:44:56 -08:00
using System.Diagnostics ;
2019-04-09 11:02:34 -07:00
using System.Linq ;
2018-01-05 12:44:57 -08:00
using MatterControl.Printing ;
2017-08-20 02:34:39 -07:00
using MatterHackers.Agg.Platform ;
2017-09-15 12:08:00 -07:00
using MatterHackers.MatterControl ;
2018-12-20 16:00:27 -08:00
using MatterHackers.MatterControl.Library.Export ;
2015-11-29 23:15:47 -08:00
using MatterHackers.MatterControl.PrinterCommunication.Io ;
2016-08-17 14:04:03 -07:00
using MatterHackers.MatterControl.SlicerConfiguration ;
2016-08-17 18:20:52 -07:00
using MatterHackers.MatterControl.Tests.Automation ;
2015-12-03 13:54:18 -08:00
using MatterHackers.VectorMath ;
2019-04-26 13:14:45 -07:00
using Newtonsoft.Json ;
2015-12-01 14:49:50 -08:00
using NUnit.Framework ;
2022-07-15 17:28:39 -07:00
using TestInvoker ;
2015-11-29 23:15:47 -08:00
namespace MatterControl.Tests.MatterControl
{
2022-07-15 17:28:39 -07:00
[TestFixture, Category("GCodeStream"), Parallelizable(ParallelScope.Children)]
2017-02-09 09:01:03 -08:00
public class GCodeStreamTests
2016-01-19 15:16:05 -08:00
{
2019-04-06 08:56:26 -07:00
[SetUp]
public void TestSetup ( )
{
2022-07-15 17:28:39 -07:00
StaticData . RootPath = MatterControlUtilities . StaticDataPath ;
MatterControlUtilities . OverrideAppDataLocation ( MatterControlUtilities . RootPath ) ;
2019-04-06 08:56:26 -07:00
}
2022-07-15 17:28:39 -07:00
[Test, ChildProcessTest]
2016-01-19 15:16:05 -08:00
public void MaxLengthStreamTests ( )
{
string [ ] lines = new string [ ]
{
"G1 X0 Y0 Z0 E0 F500" ,
"M105" ,
"G1 X18 Y0 Z0 F2500" ,
"G28" ,
"G1 X0 Y0 Z0 E0 F500" ,
} ;
// We should go back to the above code when possible. It requires making pause part and move while paused part of the stream.
// All communication should go through stream to minimize the difference between printing and controlling while not printing (all printing in essence).
string [ ] expected = new string [ ]
{
"G1 X0 Y0 Z0 E0 F500" ,
"M105" ,
2016-05-11 10:44:23 -07:00
"G1 X6 F2500" ,
"G1 X12" ,
"G1 X18" ,
2016-01-19 15:16:05 -08:00
"G28" ,
2018-12-20 16:00:27 -08:00
"G1 X0 Y0 Z0 E0 F500" ,
2016-01-19 15:16:05 -08:00
} ;
2018-11-12 15:02:47 -08:00
PrinterConfig printer = null ;
2022-05-08 18:22:11 -07:00
MaxLengthStream maxLengthStream = new MaxLengthStream ( printer , new TestGCodeStream ( printer , lines ) , 6 , true ) ;
2019-03-08 13:48:00 -08:00
ValidateStreamResponse ( expected , maxLengthStream ) ;
2016-01-19 15:16:05 -08:00
}
2022-07-15 17:28:39 -07:00
[Test, ChildProcessTest]
2019-01-02 14:08:54 -08:00
public void ExportStreamG30Tests ( )
2018-12-20 16:00:27 -08:00
{
string [ ] inputLines = new string [ ]
{
"M117 Starting Print" ,
"M104 S0" ,
"; comment line" ,
"G28 ; home all axes" ,
"G0 Z10 F1800" ,
"G0 Z11 F1800" ,
"G0 X1Y0Z9 F1800" ,
"G0 Z10 F1801" ,
"G30 Z0" ,
"M114" ,
"G0 Z10 F1800" ,
"M114" ,
"M109 S[temperature]" ,
} ;
// We should go back to the above code when possible. It requires making pause part and move while paused part of the stream.
// All communication should go through stream to minimize the difference between printing and controlling while not printing (all printing in essence).
string [ ] expected = new string [ ]
{
"M117 Starting Print" ,
"M104 S0" ,
2018-12-20 16:56:14 -08:00
"; comment line" ,
"G28 ; home all axes" ,
2018-12-20 16:00:27 -08:00
"G1 Z10 F1800" ,
"G1 Z11" ,
"G1 X1 Y0 Z9" ,
"G1 Z10 F1801" ,
"G30 Z0" ,
"M114" ,
"G1 Z10 F1800" ,
"M114" ,
"M109 S[temperature]" ,
} ;
var printer = new PrinterConfig ( new PrinterSettings ( ) ) ;
var testStream = GCodeExport . GetExportStream ( printer , new TestGCodeStream ( printer , inputLines ) , true ) ;
2019-03-08 13:48:00 -08:00
ValidateStreamResponse ( expected , testStream ) ;
2019-01-02 14:08:54 -08:00
}
2022-07-15 17:28:39 -07:00
[Test, ChildProcessTest]
2019-01-02 14:08:54 -08:00
public void SmoothieRewriteTest ( )
{
string [ ] inputLines = new string [ ]
{
"G28" ,
"M119" ,
} ;
// We should go back to the above code when possible. It requires making pause part and move while paused part of the stream.
// All communication should go through stream to minimize the difference between printing and controlling while not printing (all printing in essence).
string [ ] expected = new string [ ]
{
"G28" ,
"M280 P0 S10.6" ,
"G4 P400" ,
"M280 P0 S7" ,
"G4 P400" ,
"M117 Ready " ,
"M119" ,
"switch filament; WRITE_RAW" ,
} ;
var printer = new PrinterConfig ( new PrinterSettings ( ) ) ;
var write_filter = "\"^(G28)\", \"G28,M280 P0 S10.6,G4 P400,M280 P0 S7,G4 P400,M117 Ready \"" ;
write_filter + = "\\n\"^(M119)\", \"M119,switch filament; WRITE_RAW\"" ;
printer . Settings . SetValue ( SettingsKey . write_regex , write_filter ) ;
var testStream = GCodeExport . GetExportStream ( printer , new TestGCodeStream ( printer , inputLines ) , true ) ;
2019-03-08 13:48:00 -08:00
ValidateStreamResponse ( expected , testStream ) ;
2018-12-20 16:00:27 -08:00
}
2022-07-15 17:28:39 -07:00
[Test, ChildProcessTest]
2019-01-14 15:35:21 -08:00
public void LineCuttingOffWhenNoLevelingTest ( )
{
string [ ] inputLines = new string [ ]
{
"G1 X0Y0Z0E0 F1000" ,
"G1 X10 Y0 Z0 F1000" ,
} ;
// We should go back to the above code when possible. It requires making pause part and move while paused part of the stream.
// All communication should go through stream to minimize the difference between printing and controlling while not printing (all printing in essence).
string [ ] expected = new string [ ]
{
"G1 X0 Y0 Z0 E0 F1000" ,
"G1 X10" ,
} ;
var printer = new PrinterConfig ( new PrinterSettings ( ) ) ;
printer . Settings . SetValue ( SettingsKey . has_hardware_leveling , "1" ) ;
var testStream = GCodeExport . GetExportStream ( printer , new TestGCodeStream ( printer , inputLines ) , true ) ;
2019-03-08 13:48:00 -08:00
ValidateStreamResponse ( expected , testStream ) ;
2019-01-14 15:35:21 -08:00
}
2022-07-15 17:28:39 -07:00
[Test, ChildProcessTest]
2019-05-22 16:42:28 -07:00
public void LineCuttingOnWhenLevelingOnWithProbeTest ( )
2019-01-14 15:35:21 -08:00
{
string [ ] inputLines = new string [ ]
{
"G1 X0Y0Z0E0F1000" ,
"G1 X0Y0Z0E1F1000" ,
"G1 X10 Y0 Z0 F1000" ,
} ;
string [ ] expected = new string [ ]
{
2021-09-17 11:49:16 -07:00
PrintLevelingStream . SoftwareLevelingAppliedMessage ,
2019-01-14 15:35:21 -08:00
"G1 X0 Y0 Z-0.1 E0 F1000" ,
"G1 E1" ,
2022-04-27 11:58:19 -07:00
"G1 X1" ,
"G1 X2" ,
"G1 X3" ,
"G1 X4" ,
"G1 X5" ,
"G1 X6" ,
"G1 X7" ,
"G1 X8" ,
"G1 X9" ,
"G1 X10" ,
2019-01-14 15:35:21 -08:00
} ;
var printer = new PrinterConfig ( new PrinterSettings ( ) ) ;
2019-04-26 13:14:45 -07:00
var levelingData = new PrintLevelingData ( )
{
SampledPositions = new List < Vector3 > ( )
{
new Vector3 ( 0 , 0 , 0 ) ,
new Vector3 ( 10 , 0 , 0 ) ,
new Vector3 ( 5 , 10 , 0 )
}
} ;
2019-05-22 16:42:28 -07:00
printer . Settings . SetValue ( SettingsKey . print_leveling_data , JsonConvert . SerializeObject ( levelingData ) ) ;
printer . Settings . SetValue ( SettingsKey . has_z_probe , "1" ) ;
printer . Settings . SetValue ( SettingsKey . use_z_probe , "1" ) ;
printer . Settings . SetValue ( SettingsKey . probe_offset , "0,0,-.1" ) ;
printer . Settings . SetValue ( SettingsKey . print_leveling_enabled , "1" ) ;
var testStream = GCodeExport . GetExportStream ( printer , new TestGCodeStream ( printer , inputLines ) , true ) ;
ValidateStreamResponse ( expected , testStream ) ;
}
2022-07-15 17:28:39 -07:00
[Test, ChildProcessTest]
2019-05-22 16:42:28 -07:00
public void LineCuttingOnWhenLevelingOnNoProbeTest ( )
{
string [ ] inputLines = new string [ ]
{
"G1 X0Y0Z0E0F1000" ,
"G1 X0Y0Z0E1F1000" ,
"G1 X10 Y0 Z0 F1000" ,
} ;
string [ ] expected = new string [ ]
{
2021-09-17 11:49:16 -07:00
PrintLevelingStream . SoftwareLevelingAppliedMessage ,
2019-05-22 16:42:28 -07:00
"G1 X0 Y0 Z-0.1 E0 F1000" ,
"G1 E1" ,
2022-04-27 11:58:19 -07:00
"G1 X1" ,
"G1 X2" ,
"G1 X3" ,
"G1 X4" ,
"G1 X5" ,
"G1 X6" ,
"G1 X7" ,
"G1 X8" ,
"G1 X9" ,
"G1 X10" ,
2019-05-22 16:42:28 -07:00
} ;
var printer = new PrinterConfig ( new PrinterSettings ( ) ) ;
var levelingData = new PrintLevelingData ( )
{
SampledPositions = new List < Vector3 > ( )
{
new Vector3 ( 0 , 0 , - . 1 ) ,
new Vector3 ( 10 , 0 , - . 1 ) ,
new Vector3 ( 5 , 10 , - . 1 )
}
} ;
2019-04-26 13:14:45 -07:00
printer . Settings . SetValue ( SettingsKey . print_leveling_data , JsonConvert . SerializeObject ( levelingData ) ) ;
2019-04-02 15:17:58 -07:00
printer . Settings . SetValue ( SettingsKey . probe_offset , "0,0,-.1" ) ;
2019-01-14 15:35:21 -08:00
printer . Settings . SetValue ( SettingsKey . print_leveling_enabled , "1" ) ;
var testStream = GCodeExport . GetExportStream ( printer , new TestGCodeStream ( printer , inputLines ) , true ) ;
2019-03-08 13:48:00 -08:00
ValidateStreamResponse ( expected , testStream ) ;
2019-01-14 15:35:21 -08:00
}
2018-10-04 22:40:22 -07:00
public static GCodeStream CreateTestGCodeStream ( PrinterConfig printer , string [ ] inputLines , out List < GCodeStream > streamList )
2016-06-14 16:20:49 -07:00
{
2016-08-17 14:04:03 -07:00
streamList = new List < GCodeStream > ( ) ;
2018-11-12 15:02:47 -08:00
streamList . Add ( new TestGCodeStream ( printer , inputLines ) ) ;
2017-09-15 12:08:00 -07:00
streamList . Add ( new PauseHandlingStream ( printer , streamList [ streamList . Count - 1 ] ) ) ;
2018-11-12 15:02:47 -08:00
streamList . Add ( new QueuedCommandsStream ( printer , streamList [ streamList . Count - 1 ] ) ) ;
streamList . Add ( new RelativeToAbsoluteStream ( printer , streamList [ streamList . Count - 1 ] ) ) ;
streamList . Add ( new WaitForTempStream ( printer , streamList [ streamList . Count - 1 ] ) ) ;
2018-10-29 11:41:40 -07:00
streamList . Add ( new BabyStepsStream ( printer , streamList [ streamList . Count - 1 ] ) ) ;
2022-05-08 18:22:11 -07:00
streamList . Add ( new MaxLengthStream ( printer , streamList [ streamList . Count - 1 ] , 1 , true ) ) ;
2019-04-17 14:34:36 -07:00
streamList . Add ( new ExtrusionMultiplierStream ( printer , streamList [ streamList . Count - 1 ] ) ) ;
streamList . Add ( new FeedRateMultiplierStream ( printer , streamList [ streamList . Count - 1 ] ) ) ;
2016-08-17 14:04:03 -07:00
GCodeStream totalGCodeStream = streamList [ streamList . Count - 1 ] ;
2016-06-14 16:20:49 -07:00
return totalGCodeStream ;
}
2022-07-15 17:28:39 -07:00
[Test, ChildProcessTest]
2019-04-09 11:02:34 -07:00
public void RegexReplacementStreamIsLast ( )
{
var printer = new PrinterConfig ( new PrinterSettings ( ) ) ;
2020-11-04 15:06:29 -08:00
var context = GCodeExport . GetExportStream ( printer , new TestGCodeStream ( printer , new [ ] { "" } ) , true ) ;
2019-04-09 11:02:34 -07:00
var streamProcessors = new List < GCodeStream > ( ) ;
while ( context is GCodeStream gCodeStream )
{
streamProcessors . Add ( context ) ;
context = gCodeStream . InternalStream ;
}
Assert . IsTrue ( streamProcessors . First ( ) is ProcessWriteRegexStream , "ProcessWriteRegexStream should be the last stream in the stack" ) ;
}
2022-07-15 17:28:39 -07:00
[Test, ChildProcessTest]
2020-11-03 17:50:19 -08:00
public void CorrectEOutputPositionsG91 ( )
2016-06-14 16:20:49 -07:00
{
string [ ] inputLines = new string [ ]
{
2020-11-03 17:50:19 -08:00
"G1 E11 F300" , // E = 11
2016-06-14 16:20:49 -07:00
// Before:
2020-11-03 17:50:19 -08:00
"G92 E0" , // E = 0
2016-06-14 16:20:49 -07:00
"G91" ,
2020-11-03 17:50:19 -08:00
"G1 E - 5 F302" , // E = -5
2016-06-14 16:20:49 -07:00
"G90" ,
// After:
"G91" ,
2020-11-03 17:50:19 -08:00
"G1 E8 F150" , // E = 3
2016-06-14 16:20:49 -07:00
"G90" ,
"G4 P0" ,
2020-11-03 17:50:19 -08:00
"G92 E0" , // E = 0
2016-06-14 16:20:49 -07:00
"G4 P0" ,
"G91" ,
2020-11-03 17:50:19 -08:00
"G1 E-2 F301" , // E = -2
2016-06-14 16:20:49 -07:00
"G90" ,
} ;
// We should go back to the above code when possible. It requires making pause part and move while paused part of the stream.
// All communication should go through stream to minimize the difference between printing and controlling while not printing (all printing in essence).
string [ ] expected = new string [ ]
{
2019-01-14 15:35:21 -08:00
"G1 E11 F300" ,
"G92 E0" ,
"" ,
"G1 E-1 F302" ,
"G1 E-2" ,
"G1 E-3" ,
"G1 E-4" ,
"G1 E-5" ,
"G90" ,
2019-04-01 15:51:39 -07:00
"" , // 10
2019-01-14 15:35:21 -08:00
"G1 E-4 F150" ,
"G1 E-3" ,
"G1 E-2" ,
"G1 E-1" ,
"G1 E0" ,
"G1 E1" ,
"G1 E2" ,
"G1 E3" ,
2019-04-01 15:51:39 -07:00
"" ,
2019-01-14 15:35:21 -08:00
"G4 P0" ,
"G92 E0" ,
"G4 P0" ,
"" ,
"G1 E-1 F301" ,
"G1 E-2" ,
2019-04-01 15:51:39 -07:00
"" ,
2016-06-14 16:20:49 -07:00
} ;
2018-10-04 22:40:22 -07:00
var printer = new PrinterConfig ( new PrinterSettings ( ) ) ;
GCodeStream testStream = CreateTestGCodeStream ( printer , inputLines , out List < GCodeStream > streamList ) ;
2019-03-08 13:48:00 -08:00
ValidateStreamResponse ( expected , testStream ) ;
2016-06-14 16:20:49 -07:00
}
2022-07-15 17:28:39 -07:00
[Test, ChildProcessTest]
2020-11-03 17:50:19 -08:00
public void CorrectEOutputPositionsM83 ( )
{
string [ ] inputLines = new string [ ]
{
"G1 E11 F300" ,
// Before:
"G92 E0" ,
"M83" , // relative extruder
"G1 E - 5 F302" ,
"M82" ,
// After:
"M83" ,
"G1 E8 F150" ,
"M82" ,
"G4 P0" ,
"G92 E0" ,
"G4 P0" ,
"M83" ,
"G1 E-2 F301" ,
"M82" ,
"G1 E2 F301" ,
} ;
string [ ] expected = new string [ ]
{
"G1 E11 F300" ,
"G92 E0" ,
"" ,
"G1 E-1 F302" ,
"G1 E-2" ,
"G1 E-3" ,
"G1 E-4" ,
"G1 E-5" ,
"M82" ,
"" , // 10
"G1 E-4 F150" ,
"G1 E-3" ,
"G1 E-2" ,
"G1 E-1" ,
"G1 E0" ,
"G1 E1" ,
"G1 E2" ,
"G1 E3" ,
"" ,
"G4 P0" , // 20
"G92 E0" ,
"G4 P0" ,
"" ,
"G1 E-1 F301" ,
"G1 E-2" ,
"" ,
"G1 E-1" ,
"G1 E0" ,
"G1 E1" ,
"G1 E2" , // 30
} ;
var printer = new PrinterConfig ( new PrinterSettings ( ) ) ;
GCodeStream testStream = CreateTestGCodeStream ( printer , inputLines , out List < GCodeStream > streamList ) ;
ValidateStreamResponse ( expected , testStream ) ;
}
2022-07-15 17:28:39 -07:00
[Test, ChildProcessTest]
2020-11-03 17:50:19 -08:00
public void CorrectEOutputForMiniStartupWithM83 ( )
{
string [ ] inputLines = new string [ ]
{
"G21 ; set units to millimeters" ,
"M107 ; fan off" ,
"T0 ; set the active extruder to 0" ,
"; settings from start_gcode" ,
"M83" ,
"M104 S170 ; set hotend temperature for bed leveling" ,
"M140 S60 ; set bed temperature" ,
"M109 R170" ,
"G28" ,
"G29" ,
"M104 S215 ; set hotend temperature" ,
"G92 E0.0" ,
"G1 X0 Y0 F2400" ,
"G1 Z3 F720" ,
"G92 E0.0" ,
"G1 X5 F1000" ,
"G1 Z0 F720" ,
"G1 X10 E5 F900" ,
"G1 X15 E5" ,
"G92 E0.0" ,
"; automatic settings after start_gcode" ,
"T0 ; set the active extruder to 0" ,
"G90 ; use absolute coordinates" ,
"G92 E0 ; reset the expected extruder position" ,
"M82 ; use absolute distance for extrusion" ,
"G1 E5 F440" ,
"G1 E10" ,
} ;
string [ ] expected = new string [ ]
{
"G21 ; set units to millimeters" ,
"M107 ; fan off" ,
"T0 ; set the active extruder to 0" ,
"; settings from start_gcode" ,
"" , // set to relative e
"M104 S170 ; set hotend temperature for bed leveling" ,
"M140 S60 ; set bed temperature" ,
"M109 R170" ,
"G28" ,
"G29" , // 10
"M104 S215 ; set hotend temperature" ,
"G92 E0.0" ,
"G1 F2400" ,
"G1 Z1 F720" ,
"G1 Z2" ,
"G1 Z3" ,
"G92 E0.0" ,
"G1 X1 F1000" ,
"G1 X2" ,
"G1 X3" , // 20
"G1 X4" ,
"G1 X5" ,
"G1 F720" ,
"G1 X6 E1 F900" ,
"G1 X7 E2" ,
"G1 X8 E3" ,
"G1 X9 E4" ,
"G1 X10 E5" ,
"G1 X11 E6" ,
"G1 X12 E7" , // 30
"G1 X13 E8" ,
"G1 X14 E9" ,
"G1 X15 E10" ,
"G92 E0.0" ,
"; automatic settings after start_gcode" ,
"T0 ; set the active extruder to 0" ,
"G90 ; use absolute coordinates" ,
"G92 E0 ; reset the expected extruder position" ,
"M82 ; use absolute distance for extrusion" ,
"G1 E1 F440" , // 40
"G1 E2" ,
"G1 E3" ,
"G1 E4" ,
"G1 E5" ,
"G1 E6" ,
"G1 E7" ,
"G1 E8" ,
"G1 E9" ,
"G1 E10" ,
} ;
var printer = new PrinterConfig ( new PrinterSettings ( ) ) ;
GCodeStream testStream = CreateTestGCodeStream ( printer , inputLines , out List < GCodeStream > streamList ) ;
ValidateStreamResponse ( expected , testStream ) ;
}
2022-07-15 17:28:39 -07:00
[Test, ChildProcessTest]
2016-06-14 16:20:49 -07:00
public void CorrectZOutputPositions ( )
{
string [ ] inputLines = new string [ ]
{
"G1 Z-2 F300" ,
"G92 Z0" ,
"G1 Z5 F300" ,
"G28" ,
} ;
// We should go back to the above code when possible. It requires making pause part and move while paused part of the stream.
// All communication should go through stream to minimize the difference between printing and controlling while not printing (all printing in essence).
string [ ] expected = new string [ ]
{
2018-12-06 17:58:36 -08:00
"G1 Z-2 F300" ,
2016-06-14 16:20:49 -07:00
"G92 Z0" ,
"G1 Z1 F300" ,
"G1 Z2" ,
"G1 Z3" ,
"G1 Z4" ,
"G1 Z5" ,
"G28" ,
} ;
2018-10-04 22:40:22 -07:00
var printer = new PrinterConfig ( new PrinterSettings ( ) ) ;
GCodeStream testStream = CreateTestGCodeStream ( printer , inputLines , out List < GCodeStream > streamList ) ;
2019-03-08 13:48:00 -08:00
ValidateStreamResponse ( expected , testStream ) ;
2016-06-14 16:20:49 -07:00
}
2022-07-15 17:28:39 -07:00
[Test, ChildProcessTest]
2016-01-19 15:16:05 -08:00
public void PauseHandlingStreamTests ( )
{
2017-09-14 23:45:56 -07:00
int readX = 50 ;
2017-02-13 17:18:24 -08:00
// Validate that the number parsing code is working as expected, specifically ignoring data that appears in comments
// This is a regression that we saw in the Lulzbot Mini profile after adding macro processing.
2017-02-13 16:16:16 -08:00
GCodeFile . GetFirstNumberAfter ( "X" , "G1 Z10 E - 10 F12000 ; suck up XXmm of filament" , ref readX ) ;
2017-02-13 17:18:24 -08:00
// did not change
Assert . AreEqual ( 50 , readX , "Don't change the x if it is after a comment" ) ;
2017-02-13 16:16:16 -08:00
2017-02-13 17:18:24 -08:00
// a comments that looks more like a valid line
GCodeFile . GetFirstNumberAfter ( "X" , "G1 Z10 E - 10 F12000 ; X33" , ref readX ) ;
// did not change
2017-02-13 16:16:16 -08:00
Assert . AreEqual ( 50 , readX , "Don't change the x if it is after a comment" ) ;
2017-02-13 17:18:24 -08:00
// a line that should parse
GCodeFile . GetFirstNumberAfter ( "X" , "G1 Z10 E - 10 F12000 X33" , ref readX ) ;
// did change
Assert . AreEqual ( 33 , readX , "not in a comment, do a change" ) ;
2017-02-13 16:16:16 -08:00
2016-01-19 15:16:05 -08:00
string [ ] inputLines = new string [ ]
{
"; the printer is moving normally" ,
"G1 X10 Y10 Z10 E0" ,
"G1 X10 Y10 Z10 E10" ,
"G1 X10 Y10 Z10 E30" ,
"; the printer pauses" ,
"G91" ,
2017-02-13 16:16:16 -08:00
"G1 Z10 E - 10 F12000 ; suck up XXmm of filament" ,
2016-01-19 15:16:05 -08:00
"G90" ,
"; the user moves the printer" ,
"; the printer un-pauses" ,
"G91" ,
"G1 Z-10 E10.8 F12000" ,
"G90" ,
} ;
// We should go back to the above code when possible. It requires making pause part and move while paused part of the stream.
// All communication should go through stream to minimize the difference between printing and controlling while not printing (all printing in essence).
string [ ] expected = new string [ ]
{
"; the printer is moving normally" ,
2019-02-22 11:32:55 -08:00
"G1 X10 Y10 Z10 E0" ,
2016-06-14 16:31:35 -07:00
"G1 E10" ,
"G1 E30" ,
2016-01-19 15:16:05 -08:00
"; the printer pauses" ,
"" , // G91 is removed
2016-05-11 10:44:23 -07:00
"G1 Z20 E20 F12000" , // altered to be absolute
2016-01-19 15:16:05 -08:00
"G90" ,
"; the user moves the printer" ,
"; the printer un-pauses" ,
"" , // G91 is removed
2016-05-11 10:44:23 -07:00
"G1 Z10 E30.8" ,
2019-04-01 15:51:39 -07:00
"" , // G90 is removed
2016-01-19 15:16:05 -08:00
} ;
2018-10-04 22:40:22 -07:00
var printer = new PrinterConfig ( new PrinterSettings ( ) ) ;
GCodeStream pauseHandlingStream = CreateTestGCodeStream ( printer , inputLines , out List < GCodeStream > streamList ) ;
2019-03-08 13:48:00 -08:00
ValidateStreamResponse ( expected , pauseHandlingStream ) ;
2019-02-15 12:55:22 -08:00
}
2022-07-15 17:28:39 -07:00
[Test, ChildProcessTest, Ignore("WIP")]
2019-02-15 12:55:22 -08:00
public void SoftwareEndstopstreamTests ( )
{
string [ ] inputLines = new string [ ]
{
// test x min
// move without extrusion
"G1 X100Y100Z0E0" , // start at the bed center
"G1 X-100" , // move left off the bed
"G1 Y110" , // move while outside bounds
"G1 X100" , // move back on
// move with extrusion
"G1 X100Y100Z0E0" , // start at the bed center
"G1 X-100E10" , // move left off the bed
"G1 Y110E20" , // move while outside bounds
"G1 X100E30" , // move back on
// test x max
// test y min
// test y max
// test z min
// test z max
} ;
// We should go back to the above code when possible. It requires making pause part and move while paused part of the stream.
// All communication should go through stream to minimize the difference between printing and controlling while not printing (all printing in essence).
string [ ] expected = new string [ ]
{
// move without extrusion
2019-03-29 13:58:13 -07:00
"G1 X100 Y100 Z0 E0" , // start position
2019-02-15 12:55:22 -08:00
"G1 X0" , // clamped x
"" , // move while outside
"G1 Y110" , // first position back in bounds
"G1 X100" , // move to requested x
// move with extrusion
"G1 X100Y100Z0E0" , // start at the bed center
"G1 X-100E10" , // move left off the bed
"G1 Y110E20" , // move while outside bounds
"G1 X100E30" , // move back on
} ;
var printer = new PrinterConfig ( new PrinterSettings ( ) ) ;
var pauseHandlingStream = new SoftwareEndstopsStream ( printer , new TestGCodeStream ( printer , inputLines ) ) ;
2019-03-08 13:48:00 -08:00
ValidateStreamResponse ( expected , pauseHandlingStream ) ;
2016-01-19 15:16:05 -08:00
}
2016-08-17 14:04:03 -07:00
2022-07-15 17:28:39 -07:00
[Test, ChildProcessTest]
2016-08-17 14:04:03 -07:00
public void MorePauseHandlingStreamTests ( )
{
string [ ] inputLines = new string [ ]
{
"; the printer is moving normally" ,
"G1 X10 Y10 Z10 E0" ,
"G1 X11 Y10 Z10 E10" ,
"G1 X12 Y10 Z10 E30" ,
"; the printer pauses" ,
"@pause" ,
"; do_resume" , // just a marker for us to issue a resume
// move some more
"G1 X13 Y10 Z10 E40" ,
} ;
// We should go back to the above code when possible. It requires making pause part and move while paused part of the stream.
// All communication should go through stream to minimize the difference between printing and controlling while not printing (all printing in essence).
string [ ] expected = new string [ ]
{
"; the printer is moving normally" ,
2019-02-22 11:32:55 -08:00
"G1 X10 Y10 Z10 E0" ,
2016-08-17 14:04:03 -07:00
"G1 X11 E10" ,
"G1 X12 E30" ,
"; the printer pauses" ,
"" ,
"" ,
"G1 Z20 E20 F12000" ,
"G90" ,
"M114" ,
"" ,
"; do_resume" ,
"G92 E-10" ,
"G1 Z16.67 F3001" ,
"G1 X12.01 Y10.01 Z13.34" ,
"G1 Z10.01" ,
"G1 X12 Y10 Z10 F3000" ,
"" ,
"G1 Z0 E30.8 F12000" ,
2019-04-01 15:51:39 -07:00
"" , // G90 removed
2016-08-17 14:04:03 -07:00
"M114" ,
2018-04-22 21:46:11 -07:00
"" ,
"G1 X12.1 F1800" ,
"G1 X12.2" ,
2019-04-01 15:51:39 -07:00
"" , // G90 removed
2018-04-22 21:46:11 -07:00
"G1 X12.33 Z1.667 E32.333" ,
"G1 X12.47 Z3.333 E33.867" ,
"G1 X12.6 Z5 E35.4" ,
"G1 X12.73 Z6.667 E36.933" ,
"G1 X12.87 Z8.333 E38.467" ,
2016-08-17 14:04:03 -07:00
"G1 X13 Z10 E40" ,
} ;
// this is the pause and resume from the Eris
2018-10-04 22:40:22 -07:00
var printer = new PrinterConfig ( new PrinterSettings ( ) ) ;
printer . Settings . SetValue ( SettingsKey . pause_gcode , "G91\nG1 Z10 E - 10 F12000\n G90" ) ;
printer . Settings . SetValue ( SettingsKey . resume_gcode , "G91\nG1 Z-10 E10.8 F12000\nG90" ) ;
GCodeStream pauseHandlingStream = CreateTestGCodeStream ( printer , inputLines , out List < GCodeStream > streamList ) ;
2019-03-08 13:48:00 -08:00
ValidateStreamResponse ( expected , pauseHandlingStream , streamList ) ;
}
2016-08-17 14:04:03 -07:00
2020-12-18 18:07:37 -08:00
public static void ValidateStreamResponse ( string [ ] expected , GCodeStream testStream , List < GCodeStream > streamList = null )
2019-03-08 13:48:00 -08:00
{
2019-04-06 09:24:12 -07:00
int lineIndex = 0 ;
2019-04-06 09:36:59 -07:00
// Advance
2019-03-07 09:59:36 -08:00
string actualLine = testStream . ReadLine ( ) ;
2019-04-06 09:24:12 -07:00
string expectedLine = expected [ lineIndex + + ] ;
2019-03-07 09:59:36 -08:00
while ( actualLine ! = null )
{
2020-11-03 17:50:19 -08:00
if ( actualLine . StartsWith ( "G92 E0" ) )
2019-03-07 09:59:36 -08:00
{
2020-11-03 17:50:19 -08:00
testStream . SetPrinterPosition ( new PrinterMove ( default ( Vector3 ) , 0 , 300 ) ) ;
2019-03-07 09:59:36 -08:00
}
2020-11-03 17:50:19 -08:00
if ( actualLine . StartsWith ( "G92 Z0" ) )
2019-03-08 13:48:00 -08:00
{
testStream . SetPrinterPosition ( new PrinterMove ( new Vector3 ( ) , 0 , 0 ) ) ;
}
if ( actualLine = = "; do_resume" )
{
PauseHandlingStream pauseStream = null ;
foreach ( var stream in streamList )
{
if ( stream as PauseHandlingStream ! = null )
{
pauseStream = ( PauseHandlingStream ) stream ;
pauseStream . Resume ( ) ;
}
}
}
if ( expectedLine ! = actualLine )
2019-03-07 09:59:36 -08:00
{
int a = 0 ;
}
Debug . WriteLine ( actualLine ) ;
Assert . AreEqual ( expectedLine , actualLine , "Unexpected response from testStream" ) ;
2019-04-06 09:36:59 -07:00
// Advance
actualLine = testStream . ReadLine ( ) ;
if ( lineIndex < expected . Length )
{
expectedLine = expected [ lineIndex + + ] ;
}
2016-08-17 14:04:03 -07:00
}
}
2017-02-09 09:01:03 -08:00
2022-07-15 17:28:39 -07:00
[Test, ChildProcessTest]
2019-03-27 16:16:16 -07:00
public void KnownLayerLinesTest ( )
{
Assert . AreEqual ( 8 , GCodeFile . GetLayerNumber ( "; layer 8, Z = 0.800" ) , "Simplify3D ~ 2019" ) ;
Assert . AreEqual ( 1 , GCodeFile . GetLayerNumber ( "; LAYER:1" ) , "Cura/MatterSlice" ) ;
Assert . AreEqual ( 7 , GCodeFile . GetLayerNumber ( ";LAYER:7" ) , "Slic3r Prusa Edition 1.38.7-prusa3d on 2018-04-25" ) ;
}
2022-07-15 17:28:39 -07:00
[Test, ChildProcessTest]
2017-07-13 18:43:48 -07:00
public void WriteReplaceStreamTests ( )
{
string [ ] inputLines = new string [ ]
{
"; the printer is moving normally" ,
"G1 X10 Y10 Z10 E0" ,
"M114" ,
"G29" ,
"G28" ,
"G28 X0" ,
"M107" ,
"M107 ; extra stuff" ,
} ;
string [ ] expected = new string [ ]
{
"; the printer is moving normally" ,
"G1 X10 Y10 Z10 E0" ,
"M114" ,
"G29" ,
"G28" ,
"M115" ,
"G28 X0" ,
"M115" ,
"; none" ,
"; none ; extra stuff" ,
} ;
2018-10-04 22:40:22 -07:00
var printer = new PrinterConfig ( new PrinterSettings ( ) ) ;
printer . Settings . SetValue ( SettingsKey . write_regex , "\"^(G28)\",\"G28,M115\"\\n\"^(M107)\",\"; none\"" ) ;
2017-07-13 18:43:48 -07:00
2018-11-12 15:02:47 -08:00
var inputLinesStream = new TestGCodeStream ( printer , inputLines ) ;
var queueStream = new QueuedCommandsStream ( printer , inputLinesStream ) ;
2019-03-27 16:16:16 -07:00
var writeStream = new ProcessWriteRegexStream ( printer , queueStream , queueStream ) ;
2019-03-08 13:48:00 -08:00
ValidateStreamResponse ( expected , writeStream ) ;
2017-07-13 18:43:48 -07:00
}
2022-07-15 17:28:39 -07:00
[Test, ChildProcessTest]
2017-03-09 12:44:20 -08:00
public void FeedRateRatioChangesFeedRate ( )
2017-02-09 09:01:03 -08:00
{
2017-03-09 12:44:20 -08:00
string line ;
2017-02-09 09:01:03 -08:00
2020-07-02 14:42:11 -07:00
PrinterConfig printer = new PrinterConfig ( new PrinterSettings ( ) ) ;
2019-04-17 14:34:36 -07:00
var gcodeStream = new FeedRateMultiplierStream ( printer , new TestGCodeStream ( printer , new string [ ] { "G1 X10 F1000" , "G1 Y5 F1000" } ) ) ;
2017-02-09 09:01:03 -08:00
2020-07-01 21:59:06 -07:00
Assert . AreEqual ( 1 , ( int ) gcodeStream . FeedRateRatio , "FeedRateRatio should default to 1" ) ;
2017-03-09 12:44:20 -08:00
line = gcodeStream . ReadLine ( ) ;
2017-02-09 09:01:03 -08:00
2017-03-09 12:44:20 -08:00
Assert . AreEqual ( "G1 X10 F1000" , line , "FeedRate should remain unchanged when FeedRateRatio is 1.0" ) ;
2020-07-01 21:59:06 -07:00
gcodeStream . FeedRateRatio = 2 ;
2017-03-09 12:44:20 -08:00
line = gcodeStream . ReadLine ( ) ;
Assert . AreEqual ( "G1 Y5 F2000" , line , "FeedRate should scale from F1000 to F2000 when FeedRateRatio is 2x" ) ;
2017-02-09 09:01:03 -08:00
}
2022-07-15 17:28:39 -07:00
[Test, ChildProcessTest]
2017-03-09 12:44:20 -08:00
public void ExtrusionRatioChangesExtrusionAmount ( )
2017-02-09 09:01:03 -08:00
{
2017-03-09 12:44:20 -08:00
string line ;
2017-02-09 09:01:03 -08:00
2020-07-02 14:42:11 -07:00
PrinterConfig printer = new PrinterConfig ( new PrinterSettings ( ) ) ;
2019-04-17 14:34:36 -07:00
var gcodeStream = new ExtrusionMultiplierStream ( printer , new TestGCodeStream ( printer , new string [ ] { "G1 E10" , "G1 E0 ; Move back to 0" , "G1 E12" } ) ) ;
2017-03-09 12:44:20 -08:00
2020-07-01 21:59:06 -07:00
Assert . AreEqual ( 1 , ( int ) gcodeStream . ExtrusionRatio , "ExtrusionRatio should default to 1" ) ;
2017-03-09 12:44:20 -08:00
line = gcodeStream . ReadLine ( ) ;
// Move back to E0
gcodeStream . ReadLine ( ) ;
2019-04-17 14:34:36 -07:00
Assert . AreEqual ( "G1 E10" , line , "ExtrusionMultiplier should remain unchanged when FeedRateRatio is 1.0" ) ;
2017-02-09 09:01:03 -08:00
2020-07-01 21:59:06 -07:00
gcodeStream . ExtrusionRatio = 2 ;
2017-02-09 09:01:03 -08:00
2017-03-09 12:44:20 -08:00
line = gcodeStream . ReadLine ( ) ;
2017-02-09 09:01:03 -08:00
2019-04-17 14:34:36 -07:00
Assert . AreEqual ( "G1 E24" , line , "ExtrusionMultiplier should scale from E12 to E24 when ExtrusionRatio is 2x" ) ;
2017-02-09 09:01:03 -08:00
}
2016-01-19 15:16:05 -08:00
}
public class TestGCodeStream : GCodeStream
{
private int index = 0 ;
private string [ ] lines ;
2018-11-12 15:02:47 -08:00
public TestGCodeStream ( PrinterConfig printer , string [ ] lines )
: base ( printer )
2016-01-19 15:16:05 -08:00
{
this . lines = lines ;
}
public override void Dispose ( )
{
}
public override string ReadLine ( )
{
2019-04-06 09:36:59 -07:00
return index < lines . Length ? lines [ index + + ] : null ;
2016-01-19 15:16:05 -08:00
}
public override void SetPrinterPosition ( PrinterMove position )
{
}
2019-03-01 13:52:03 -08:00
public override GCodeStream InternalStream = > null ;
public override string DebugInfo = > "" ;
2016-01-19 15:16:05 -08:00
}
2015-12-01 14:49:50 -08:00
}