def test_g28(self): # no parameters gcode = "G28" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G28") self.assertDictEqual({}, parsed.parameters) # all parameters, funky spaces gcode = "g 2 8 xy zw; some kind of comment" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G28") self.assertIsNone(parsed.parameters["X"]) self.assertIsNone(parsed.parameters["Y"]) self.assertIsNone(parsed.parameters["Z"]) self.assertIsNone(parsed.parameters["W"]) # all parameters, no spaces gcode = "g28wzxy; some kind of comment" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G28") self.assertIsNone(parsed.parameters["X"]) self.assertIsNone(parsed.parameters["Y"]) self.assertIsNone(parsed.parameters["Z"]) self.assertIsNone(parsed.parameters["W"]) # some parameters gcode = "g28 xy; some kind of comment" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G28") self.assertIsNone(parsed.parameters["X"]) self.assertIsNone(parsed.parameters["Y"]) self.assertNotIn("Z", parsed.parameters) self.assertNotIn("W", parsed.parameters)
def test_unknown_command(self): gcode = "G9999fdafdsafdafsd" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G9999") self.assertIsNone(parsed.parameters) gcode = "G9999" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G9999") self.assertIsNone(parsed.parameters)
def test_g21(self): # no parameters gcode = "G21" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G21") self.assertDictEqual({}, parsed.parameters) # with parameters (bogus) gcode = "G21X100fdafdsa; Here is a comment" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G21") self.assertDictEqual({}, parsed.parameters)
def test_IsAtCurrentPosition(self): # Received: x:119.91,y:113.34,z:2.1,e:0.0, Expected: # x:119.9145519,y:113.33847,z:2.1 # G1 X119.915 Y113.338 F7200 position = Position(self.Settings, self.OctoprintPrinterProfile, False) position.update(Commands.parse("M83")) position.update(Commands.parse("G90")) position.update(Commands.parse("G28")) position.update(Commands.parse("G1 X119.915 Y113.338 Z2.1 F7200")) self.assertTrue(position.is_at_current_position(119.91, 113.34, 2.1)) position.update(Commands.parse("g0 x120 y121 z2.1")) self.assertTrue(position.is_at_previous_position(119.91, 113.34, 2.1))
def test_reset(self): """Test init state.""" position = Position(self.Settings, self.OctoprintPrinterProfile, False) # reset all initialized vars to something else position.update(Commands.parse("G28")) position.update(Commands.parse("G0 X1 Y1 Z1")) # reset position = Position(self.Settings, self.OctoprintPrinterProfile, False) # test initial state self.assertEqual(len(position.Positions), 0) self.assertIsNone(position.SavedPosition)
def test_m105(self): gcode = "m105;" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "M105") self.assertDictEqual(parsed.parameters, {}) gcode = "m105X1;" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "M105") self.assertDictEqual(parsed.parameters, {}) gcode = "m105fdsafdsafdsfsdfsd;" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "M105") self.assertDictEqual(parsed.parameters, {})
def test_parameter_repetition(self): # test parameter repetition gcode = "g28 xxz" parsed = Commands.parse(gcode) self.assertIsNone(parsed.cmd) self.assertIsNotNone(parsed.error) self.assertNotEqual(len(parsed.error), 0) # test parameter repetition wrapped in comments gcode = "(comment in the front)g(comment in middle)2()8x(another comment in middle)x(comment between" \ " address and value)100()1 . 1(another); Here is a comment" parsed = Commands.parse(gcode) self.assertIsNone(parsed.cmd) self.assertIsNotNone(parsed.error) self.assertNotEqual(len(parsed.error), 0)
def test_multiple_signs_parameter(self): # test multiple signs in parameter 1 gcode = "(comment in the front)g(comment in middle)2()8(another comment in middle)x(comment between" \ " address and value)+100()1 . 1+(another); Here is a comment" parsed = Commands.parse(gcode) self.assertIsNone(parsed.cmd) self.assertIsNotNone(parsed.error) self.assertNotEqual(len(parsed.error), 0) # test multiple signs in parameter 2 gcode = "(comment in the front)g(comment in middle)2()8x(another comment in middle)x(comment between" \ " address and value)++100()1 . 1(another); Here is a comment" parsed = Commands.parse(gcode) self.assertIsNone(parsed.cmd) self.assertIsNotNone(parsed.error) self.assertNotEqual(len(parsed.error), 0)
def test_parse_int_negative(self): # test negative F error gcode = "G00 F- 1 09 " parsed = Commands.parse(gcode) self.assertIsNone(parsed.cmd) self.assertIsNotNone(parsed.error) self.assertNotEqual(len(parsed.error), 0)
def test_multiple_decimals_command(self): # test multiple decimal points in parameter 2 gcode = "G28.0." parsed = Commands.parse(gcode) self.assertIsNone(parsed.cmd) self.assertIsNotNone(parsed.error) self.assertNotEqual(len(parsed.error), 0)
def test_g0(self): # no parameters gcode = "g0" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G0") self.assertDictEqual({}, parsed.parameters) # no parameters, double 0 gcode = "g00" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G0") self.assertDictEqual({}, parsed.parameters) # all parameters with comment gcode = "g0 x100 y200.0 z3.0001 e1.1 f7200.000; Here is a comment" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G0") self.assertEqual(parsed.parameters["X"], 100) self.assertEqual(parsed.parameters["Y"], 200.0) self.assertEqual(parsed.parameters["Z"], 3.0001) self.assertEqual(parsed.parameters["E"], 1.1) self.assertEqual(parsed.parameters["F"], 7200.000) # all parameters, no spaces gcode = "g0x100y200.0z3.0001e1.1f7200.000" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G0") self.assertEqual(parsed.parameters["X"], 100) self.assertEqual(parsed.parameters["Y"], 200.0) self.assertEqual(parsed.parameters["Z"], 3.0001) self.assertEqual(parsed.parameters["E"], 1.1) self.assertEqual(parsed.parameters["F"], 7200.000) # all parameters, funky spaces gcode = "g 0 x 10 0 y2 00 .0z 3.0 001 e1. 1 f72 00 .000 " parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G0") self.assertEqual(parsed.parameters["X"], 100) self.assertEqual(parsed.parameters["Y"], 200.0) self.assertEqual(parsed.parameters["Z"], 3.0001) self.assertEqual(parsed.parameters["E"], 1.1) self.assertEqual(parsed.parameters["F"], 7200.000)
def test_g90_influences_extruder_UpdatePosition(self): """Test G90 for machines where it influences the coordinate system of the extruder.""" position = Position(self.Settings, self.OctoprintPrinterProfile, True) # Make sure the axis is homed position.update(Commands.parse("G28")) # set absolute mode with G90 position.update(Commands.parse("g90")) # update the position to 10 (absolute) position.update_position(e=10) self.assertEqual(position.e(), 10) # update the position to 10 again (absolute) to make sure we are in absolute # coordinates. position.update_position(e=10) self.assertEqual(position.e(), 10) # set relative mode with G90 position.update(Commands.parse("g91")) # update the position to 20 (relative) position.update_position(e=20) self.assertEqual(position.e(), 30)
def test_t(self): gcode = "T?" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "T") self.assertDictEqual(parsed.parameters, {"T": None}) gcode = " T? " parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "T") self.assertDictEqual(parsed.parameters, {"T": None}) gcode = " T ? " parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "T") self.assertDictEqual(parsed.parameters, {"T": None}) gcode = "T1;" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "T") self.assertDictEqual(parsed.parameters, {"T": 1}) gcode = "T 1 ;" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "T") self.assertDictEqual(parsed.parameters, {"T": 1}) gcode = "T 1.11 ;" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "T") self.assertDictEqual(parsed.parameters, {"T": 1})
def test_G92AbsoluteMovement(self): """Test the G92 command, move in absolute mode and test results.""" position = Position(self.Settings, self.OctoprintPrinterProfile, False) # set homed axis, absolute coordinates, and set position position.update(Commands.parse("G28")) position.update(Commands.parse("G90")) position.update(Commands.parse("G1 x100 y200 z150")) position.update(Commands.parse("G92 x10 y20 z30")) self.assertEqual(position.x(), 100) self.assertEqual(position.x_offset(), 90) self.assertEqual(position.y(), 200) self.assertEqual(position.y_offset(), 180) self.assertEqual(position.z(), 150) self.assertEqual(position.z_offset(), 120) # move to origin position.update(Commands.parse("G1 x-90 y-180 z-120")) self.assertEqual(position.x(), 0) self.assertEqual(position.x_offset(), 90) self.assertEqual(position.y(), 0) self.assertEqual(position.y_offset(), 180) self.assertEqual(position.z(), 0) self.assertEqual(position.z_offset(), 120) # move back position.update(Commands.parse("G1 x0 y0 z0")) self.assertEqual(position.x(), 90) self.assertEqual(position.x_offset(), 90) self.assertEqual(position.y(), 180) self.assertEqual(position.y_offset(), 180) self.assertEqual(position.z(), 120) self.assertEqual(position.z_offset(), 120)
def test_GetSnapshotGcode_Fixed_AbsoluteCoordintes_ExtruderRelative(self): """Test snapshot gcode in absolute coordinate system with relative extruder and fixed coordinate stabilization """ # adjust the settings for absolute position and create the snapshot gcode generator self.Settings.profiles.current_stabilization().x_type = "fixed_coordinate" self.Settings.profiles.current_stabilization().x_fixed_coordinate = 10 self.Settings.profiles.current_stabilization().y_type = "fixed_coordinate" self.Settings.profiles.current_stabilization().y_fixed_coordinate = 20 snapshot_gcode_generator = SnapshotGcodeGenerator( self.Settings, self.create_octoprint_printer_profile()) self.Extruder.is_retracted = lambda: True self.Position.update(Commands.parse("G90")) self.Position.update(Commands.parse("M83")) self.Position.update(Commands.parse("G28")) self.Position.update(Commands.parse("G0 X95 Y95 Z0.2 F3600")) parsed_command = Commands.parse("G0 X100 Y100") self.Position.update(parsed_command) snapshot_gcode = snapshot_gcode_generator.create_snapshot_gcode( self.Position, None, parsed_command) gcode_commands = snapshot_gcode.snapshot_gcode() # verify the created gcodegcode_commands self.assertEqual(gcode_commands[0], "G1 E-4.00000 F4800") self.assertEqual(gcode_commands[1], "G1 X10.000 Y20.000 F10800") self.assertEqual(gcode_commands[2], "G1 X100.000 Y100.000") self.assertEqual(gcode_commands[3], "G1 E4.00000 F3000") self.assertEqual(gcode_commands[4], "G1 F3600") self.assertEqual(gcode_commands[5], parsed_command.gcode) # verify the return coordinates self.assertEqual(snapshot_gcode.ReturnX, 100) self.assertEqual(snapshot_gcode.ReturnY, 100) self.assertEqual(snapshot_gcode.ReturnZ, 0.2) self.assertEqual(snapshot_gcode.X, 10) self.assertEqual(snapshot_gcode.Y, 20) self.assertEqual(snapshot_gcode.Z, None)
def test_G92SetPosition(self): """Test the G92 command, settings the position.""" position = Position(self.Settings, self.OctoprintPrinterProfile, False) # no homed axis position.update(Commands.parse("G92 x10 y20 z30")) self.assertEqual(position.x(), 10) self.assertEqual(position.y(), 20) self.assertEqual(position.z(), 30) self.assertFalse(position.has_homed_axes()) # set homed axis, absolute coordinates, and set position position.update(Commands.parse("G28")) position.update(Commands.parse("G90")) position.update(Commands.parse("G1 x100 y200 z150")) position.update(Commands.parse("G92 x10 y20 z30")) self.assertEqual(position.x(), 100) self.assertEqual(position.x_offset(), 90) self.assertEqual(position.y(), 200) self.assertEqual(position.y_offset(), 180) self.assertEqual(position.z(), 150) self.assertEqual(position.z_offset(), 120) # Move to same position and retest position.update(Commands.parse("G1 x0 y0 z0")) self.assertEqual(position.x(), 90) self.assertEqual(position.x_offset(), 90) self.assertEqual(position.y(), 180) self.assertEqual(position.y_offset(), 180) self.assertEqual(position.z(), 120) self.assertEqual(position.z_offset(), 120) # Move and retest position.update(Commands.parse("G1 x-10 y10 z20")) self.assertEqual(position.x(), 80) self.assertEqual(position.x_offset(), 90) self.assertEqual(position.y(), 190) self.assertEqual(position.y_offset(), 180) self.assertEqual(position.z(), 140) self.assertEqual(position.z_offset(), 120) # G92 with no parameters position.update(Commands.parse("G92")) self.assertEqual(position.x(), 80) self.assertEqual(position.x_offset(), 80) self.assertEqual(position.y(), 190) self.assertEqual(position.y_offset(), 190) self.assertEqual(position.z(), 140) self.assertEqual(position.z_offset(), 140)
def test_g1(self): # no parameters gcode = "g1" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G1") self.assertDictEqual({}, parsed.parameters) # no parameters, double 0 gcode = "g01" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G1") self.assertDictEqual({}, parsed.parameters) # all parameters with comment gcode = "g1 x100 y200.0 z3.0001 e1.1 f7200.000; Here is a comment" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G1") self.assertEqual(parsed.parameters["X"], 100) self.assertEqual(parsed.parameters["Y"], 200.0) self.assertEqual(parsed.parameters["Z"], 3.0001) self.assertEqual(parsed.parameters["E"], 1.1) self.assertEqual(parsed.parameters["F"], 7200.000) # all parameters, no spaces gcode = "g1x100y200.0z3.0001e1.1f7200.000" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G1") self.assertEqual(parsed.parameters["X"], 100) self.assertEqual(parsed.parameters["Y"], 200.0) self.assertEqual(parsed.parameters["Z"], 3.0001) self.assertEqual(parsed.parameters["E"], 1.1) self.assertEqual(parsed.parameters["F"], 7200.000) # all parameters, funky spaces gcode = "g 01 x 10 0 y2 00 .0z 3.0 001 e1. 1 f72 00 .000 " parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G1") self.assertEqual(parsed.parameters["X"], 100) self.assertEqual(parsed.parameters["Y"], 200.0) self.assertEqual(parsed.parameters["Z"], 3.0001) self.assertEqual(parsed.parameters["E"], 1.1) self.assertEqual(parsed.parameters["F"], 7200.000) # from issue 86 gcode = "G1 X -18 Y95 F1000" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G1") self.assertEqual(parsed.parameters["X"], -18) self.assertEqual(parsed.parameters["Y"], 95) self.assertNotIn("Z", parsed.parameters) self.assertNotIn("E", parsed.parameters) self.assertEqual(parsed.parameters["F"], 1000)
def test_G92RelativeMovement(self): """Test the G92 command, move in relative mode and test results.""" position = Position(self.Settings, self.OctoprintPrinterProfile, False) # set homed axis, relative coordinates, and set position position.update(Commands.parse("G28")) position.update(Commands.parse("G91")) position.update(Commands.parse("G1 x100 y200 z150")) position.update(Commands.parse("G92 x10 y20 z30")) self.assertEqual(position.x(), 100) self.assertEqual(position.x_offset(), 90) self.assertEqual(position.y(), 200) self.assertEqual(position.y_offset(), 180) self.assertEqual(position.z(), 150) self.assertEqual(position.z_offset(), 120) # move to origin position.update(Commands.parse("G1 x-100 y-200 z-150")) self.assertEqual(position.x(), 0) self.assertEqual(position.x_offset(), 90) self.assertEqual(position.y(), 0) self.assertEqual(position.y_offset(), 180) self.assertEqual(position.z(), 0) self.assertEqual(position.z_offset(), 120) # advance each axis position.update(Commands.parse("G1 x1 y2 z3")) self.assertEqual(position.x(), 1) self.assertEqual(position.x_offset(), 90) self.assertEqual(position.y(), 2) self.assertEqual(position.y_offset(), 180) self.assertEqual(position.z(), 3) self.assertEqual(position.z_offset(), 120) # advance again position.update(Commands.parse("G1 x1 y2 z3")) self.assertEqual(position.x(), 2) self.assertEqual(position.x_offset(), 90) self.assertEqual(position.y(), 4) self.assertEqual(position.y_offset(), 180) self.assertEqual(position.z(), 6) self.assertEqual(position.z_offset(), 120)
def test_UpdatePosition_force(self): """Test the UpdatePosition function with the force option set to true.""" position = Position(self.Settings, self.OctoprintPrinterProfile, False) position.update(Commands.parse("G28")) position.update_position(x=0, y=0, z=0, e=0, force=True) self.assertEqual(position.x(), 0) self.assertEqual(position.y(), 0) self.assertEqual(position.z(), 0) self.assertEqual(position.e(), 0) position.update_position(x=1, y=2, z=3, e=4, force=True) self.assertEqual(position.x(), 1) self.assertEqual(position.y(), 2) self.assertEqual(position.z(), 3) self.assertEqual(position.e(), 4) position.update_position(x=None, y=None, z=None, e=None, force=True) self.assertEqual(position.x(), 1) self.assertEqual(position.y(), 2) self.assertEqual(position.z(), 3) self.assertEqual(position.e(), 4)
def test_inline_comments(self): gcode = "g28(this is an inline commentx)yz; Here is a comment" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G28") self.assertFalse("X" in parsed.parameters) self.assertIsNone(parsed.parameters["Y"]) self.assertIsNone(parsed.parameters["Z"]) gcode = "g28(this is an inline commentx); Here is a comment" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G28") self.assertFalse("X" in parsed.parameters) self.assertFalse("Y" in parsed.parameters) self.assertFalse("Z" in parsed.parameters) gcode = "(comment in the front)g28; Here is a comment" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G28") self.assertFalse("X" in parsed.parameters) self.assertFalse("Y" in parsed.parameters) self.assertFalse("Z" in parsed.parameters) gcode = "(comment in the front)g28(comment in back); Here is a comment" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G28") self.assertFalse("X" in parsed.parameters) self.assertFalse("Y" in parsed.parameters) self.assertFalse("Z" in parsed.parameters) gcode = "(comment in the front)g(comment in middle)28(comment in back); Here is a comment" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G28") self.assertFalse("X" in parsed.parameters) self.assertFalse("Y" in parsed.parameters) self.assertFalse("Z" in parsed.parameters) gcode = "(comment in the front)g(comment in middle)2()8(another comment in middle)x(comment between" \ "address and value)100()1 . 1(another); Here is a comment" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G28") self.assertEqual(parsed.parameters["X"], 1001.1) self.assertFalse("Y" in parsed.parameters) self.assertFalse("Z" in parsed.parameters)
def test_comments(self): """Try to parse the G0 Command, parsed.parameters and comment""" gcode = ";" parsed = Commands.parse(gcode) self.assertIsNone(parsed.cmd) self.assertIsNone(parsed.parameters) gcode = " ;" parsed = Commands.parse(gcode) self.assertIsNone(parsed.cmd) self.assertIsNone(parsed.parameters) gcode = "; " parsed = Commands.parse(gcode) self.assertIsNone(parsed.cmd) self.assertIsNone(parsed.parameters) gcode = "; " parsed = Commands.parse(gcode) self.assertIsNone(parsed.cmd) self.assertIsNone(parsed.parameters) gcode = "%" parsed = Commands.parse(gcode) self.assertIsNone(parsed.cmd) self.assertIsNone(parsed.parameters) gcode = "% " parsed = Commands.parse(gcode) self.assertIsNone(parsed.cmd) self.assertIsNone(parsed.parameters) gcode = "% " parsed = Commands.parse(gcode) self.assertIsNone(parsed.cmd) self.assertIsNone(parsed.parameters) gcode = " % this is a comment" parsed = Commands.parse(gcode) self.assertIsNone(parsed.cmd) self.assertIsNone(parsed.parameters) gcode = "g0 x100 y200.0 z3.0001 e1.1 f7200.000; Here is a comment" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G0") self.assertEqual(parsed.parameters["X"], 100) self.assertEqual(parsed.parameters["Y"], 200.0) self.assertEqual(parsed.parameters["Z"], 3.0001) self.assertEqual(parsed.parameters["E"], 1.1) self.assertEqual(parsed.parameters["F"], 7200.000) gcode = "g0x100y200.0z3.0001e1.1f7200.000; Here is a comment" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G0") self.assertEqual(parsed.parameters["X"], 100) self.assertEqual(parsed.parameters["Y"], 200.0) self.assertEqual(parsed.parameters["Z"], 3.0001) self.assertEqual(parsed.parameters["E"], 1.1) self.assertEqual(parsed.parameters["F"], 7200.000) # test signs 1 gcode = "g0x+100y-200.0z - 3.0001e +1.1f 7200.000; Here is a comment" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G0") self.assertEqual(parsed.parameters["X"], 100) self.assertEqual(parsed.parameters["Y"], -200.0) self.assertEqual(parsed.parameters["Z"], -3.0001) self.assertEqual(parsed.parameters["E"], 1.1) self.assertEqual(parsed.parameters["F"], 7200.000) # test signs 2 gcode = "g0x-100y + 200.0z+ 3.0001e -1.1f + 7200.000; Here is a comment" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G0") self.assertEqual(parsed.parameters["X"], -100) self.assertEqual(parsed.parameters["Y"], 200.0) self.assertEqual(parsed.parameters["Z"], 3.0001) self.assertEqual(parsed.parameters["E"], -1.1) self.assertEqual(parsed.parameters["F"], 7200.000) gcode = "g28xyz; Here is a comment" parsed = Commands.parse(gcode) self.assertEqual(parsed.cmd, "G28") self.assertIsNone(parsed.parameters["X"]) self.assertIsNone(parsed.parameters["Y"]) self.assertIsNone(parsed.parameters["Z"])
def test_Update(self): """Test the Update() function, which accepts gcode and updates the current position state and extruder state.""" position = Position(self.Settings, self.OctoprintPrinterProfile, False) # no homed axis position.update(Commands.parse("G1 x100 y200 z300")) self.assertIsNone(position.x()) self.assertIsNone(position.y()) self.assertIsNone(position.z()) # set relative extruder and absolute xyz, home axis and update absolute position position.update(Commands.parse("M83")) position.update(Commands.parse("G90")) position.update(Commands.parse("G28")) position.update(Commands.parse("G1 x100 y200 z150")) self.assertEqual(position.x(), 100) self.assertEqual(position.y(), 200) self.assertEqual(position.z(), 150) # move again and retest position.update(Commands.parse("G1 x101 y199 z151")) self.assertEqual(position.x(), 101) self.assertEqual(position.y(), 199) self.assertEqual(position.z(), 151) # switch to relative and update position position.update(Commands.parse("G91")) position.update(Commands.parse("G1 x-1 y-1 z1.0")) self.assertEqual(position.x(), 100) self.assertEqual(position.y(), 198) self.assertEqual(position.z(), 152) # move again and retest position.update(Commands.parse("G1 x-99 y-196 z-149.0")) self.assertEqual(position.x(), 1) self.assertEqual(position.y(), 2) self.assertEqual(position.z(), 3) # go back to absolute and move to origin position.update(Commands.parse("G90")) position.update(Commands.parse("G1 x0 y0 z0.0")) self.assertEqual(position.x(), 0) self.assertEqual(position.y(), 0) self.assertEqual(position.z(), 0)
def test_UpdatePosition_noforce(self): """Test the UpdatePosition function with the force option set to true.""" position = Position(self.Settings, self.OctoprintPrinterProfile, False) # no homed axis position.update_position(x=0, y=0, z=0, e=0) self.assertIsNone(position.x()) self.assertIsNone(position.y()) self.assertIsNone(position.z()) self.assertIsNone(position.e(), 0) # set homed axis, test absolute position (default) position.update(Commands.parse("G28")) position.update_position(x=0, y=0, z=0) self.assertEqual(position.x(), 0) self.assertEqual(position.y(), 0) self.assertEqual(position.z(), 0) self.assertEqual(position.e(), 0) # update absolute position position.update_position(x=1, y=2, z=3) self.assertEqual(position.x(), 1) self.assertEqual(position.y(), 2) self.assertEqual(position.z(), 3) self.assertEqual(position.e(), 0) # set relative position position.update(Commands.parse("G91")) position.update_position(x=1, y=1, z=1) self.assertEqual(position.x(), 2) self.assertEqual(position.y(), 3) self.assertEqual(position.z(), 4) self.assertEqual(position.e(), 0) # set extruder absolute position.update(Commands.parse("M82")) position.update_position(e=100) self.assertEqual(position.x(), 2) self.assertEqual(position.y(), 3) self.assertEqual(position.z(), 4) self.assertEqual(position.e(), 100) position.update_position(e=-10) self.assertEqual(position.x(), 2) self.assertEqual(position.y(), 3) self.assertEqual(position.z(), 4) self.assertEqual(position.e(), -10) # set extruder relative position.update(Commands.parse("M83")) position.update_position(e=20) self.assertEqual(position.x(), 2) self.assertEqual(position.y(), 3) self.assertEqual(position.z(), 4) self.assertEqual(position.e(), 10) position.update_position(e=-1) self.assertEqual(position.x(), 2) self.assertEqual(position.y(), 3) self.assertEqual(position.z(), 4) self.assertEqual(position.e(), 9) position.update_position(x=1, y=2, z=3, e=4, force=True) self.assertEqual(position.x(), 1) self.assertEqual(position.y(), 2) self.assertEqual(position.z(), 3) self.assertEqual(position.e(), 4) position.update_position(x=None, y=None, z=None, e=None, force=True) self.assertEqual(position.x(), 1) self.assertEqual(position.y(), 2) self.assertEqual(position.z(), 3) self.assertEqual(position.e(), 4)
def test_HeightAndLayerChanges(self): """Test the height and layer changes.""" position = Position(self.Settings, self.OctoprintPrinterProfile, False) # test initial state self.assertIsNone(position.height()) self.assertIsNone(position.layer(), None) self.assertFalse(position.is_layer_change()) # check without homed axis position.update(Commands.parse("G1 x0 y0 z0.20000 e1")) self.assertEqual(position.height(), 0) self.assertEqual(position.layer(), 0) self.assertFalse(position.is_layer_change()) # set homed axis, absolute xyz coordinates, relative extruder coordinates and check height and layer position.update(Commands.parse("M83")) position.update(Commands.parse("G90")) position.update(Commands.parse("G28")) self.assertEqual(position.height(), 0) self.assertEqual(position.layer(), 0) self.assertFalse(position.is_layer_change()) # move without extruding, height and layer should not change position.update(Commands.parse("G1 x100 y200 z150")) self.assertEqual(position.height(), 0) self.assertEqual(position.layer(), 0) self.assertFalse(position.is_layer_change()) # move to origin, height and layer stuff should stay the same position.update(Commands.parse("G1 x0 y0 z0")) self.assertEqual(position.height(), 0) self.assertEqual(position.layer(), 0) self.assertFalse(position.is_layer_change()) # extrude, height change! position.update(Commands.parse("G1 x0 y0 z0 e1")) self.assertEqual(position.height(), 0) self.assertEqual(position.layer(), 1) self.assertTrue(position.is_layer_change()) # extrude higher, update layer., this will get rounded to 0.2 position.update(Commands.parse("G1 x0 y0 z0.1999 e1")) self.assertEqual(position.height(), 0.2) self.assertEqual(position.layer(), 2) self.assertTrue(position.is_layer_change()) # extrude just slightly higher, but with rounding on the same layer position.update(Commands.parse("G1 x0 y0 z0.20000 e1")) self.assertEqual(position.height(), .2) self.assertEqual(position.layer(), 2) self.assertFalse(position.is_layer_change()) # extrude again on same layer - Height Previous should now be updated, and # is_layer_change should be false position.update(Commands.parse("G1 x0 y0 z0.20000 e1")) self.assertEqual(position.height(), .2) self.assertEqual(position.layer(), 2) self.assertFalse(position.is_layer_change()) # extrude again on same layer - No changes position.update(Commands.parse("G1 x0 y0 z0.20000 e1")) self.assertEqual(position.height(), .2) self.assertEqual(position.layer(), 2) self.assertFalse(position.is_layer_change()) # extrude below the current layer - No changes position.update(Commands.parse("G1 x0 y0 z0.00000 e1")) self.assertEqual(position.height(), .2) self.assertEqual(position.layer(), 2) self.assertFalse(position.is_layer_change()) # extrude up higher and change the height/layer. Should never happen, but # it's an interesting test case position.update(Commands.parse("G1 x0 y0 z0.60000 e1")) self.assertEqual(position.height(), .6) self.assertEqual(position.layer(), 3) self.assertTrue(position.is_layer_change()) # extrude up again position.update(Commands.parse("G1 x0 y0 z0.65000 e1")) self.assertEqual(position.height(), .65) self.assertEqual(position.layer(), 4) self.assertTrue(position.is_layer_change()) # extrude on previous layer position.update(Commands.parse("G1 x0 y0 z0.60000 e1")) self.assertEqual(position.height(), .65) self.assertEqual(position.layer(), 4) self.assertFalse(position.is_layer_change()) # extrude on previous layer again position.update(Commands.parse("G1 x0 y0 z0.60000 e1")) self.assertEqual(position.height(), .65) self.assertEqual(position.layer(), 4) self.assertFalse(position.is_layer_change()) # move up but do not extrude position.update(Commands.parse("G1 x0 y0 z0.70000")) self.assertEqual(position.height(), .65) self.assertEqual(position.layer(), 4) self.assertFalse(position.is_layer_change()) # move up but do not extrude a second time position.update(Commands.parse("G1 x0 y0 z0.80000")) self.assertEqual(position.height(), .65) self.assertEqual(position.layer(), 4) self.assertFalse(position.is_layer_change()) # extrude at a different height position.update(Commands.parse("G1 x0 y0 z0.80000 e.1")) position.update(Commands.parse("G1 x0 y0 z0.85000 e.1")) self.assertEqual(.85, position.height()) self.assertEqual(6, position.layer()) self.assertTrue(position.is_layer_change())
def test_ExtruderMovement(self): """Test the M82 and M83 command.""" position = Position(self.Settings, self.OctoprintPrinterProfile, False) previous_pos = Pos(self.Settings.profiles.current_printer(), self.OctoprintPrinterProfile) # test initial position self.assertIsNone(position.e()) self.assertIsNone(position.is_extruder_relative()) self.assertIsNone(position.e_relative_pos(previous_pos)) # set extruder to relative coordinates position.update(Commands.parse("M83")) # test movement previous_pos = Pos(self.Settings.profiles.current_printer(), self.OctoprintPrinterProfile, position.get_position()) position.update(Commands.parse("G0 E100")) self.assertEqual(position.e(), 100) # this is somewhat reversed from what we do in the position.py module # there we update the pos() object and compare to the current state, so # comparing the current state to the # previous will result in the opposite sign self.assertEqual(position.e_relative_pos(previous_pos), -100) # switch to absolute movement previous_pos = Pos(self.Settings.profiles.current_printer(), self.OctoprintPrinterProfile, position.get_position()) position.update(Commands.parse("M82")) self.assertFalse(position.is_extruder_relative()) self.assertEqual(position.e(), 100) self.assertEqual(position.e_relative_pos(previous_pos), 0) # move to -25 previous_pos = Pos(self.Settings.profiles.current_printer(), self.OctoprintPrinterProfile, position.get_position()) position.update(Commands.parse("G0 E-25")) self.assertEqual(position.e(), -25) self.assertEqual(position.e_relative_pos(previous_pos), 125) # test movement to origin previous_pos = Pos(self.Settings.profiles.current_printer(), self.OctoprintPrinterProfile, position.get_position()) position.update(Commands.parse("G0 E0")) self.assertEqual(position.e(), 0) self.assertEqual(position.e_relative_pos(previous_pos), -25) # switch to relative position previous_pos = Pos(self.Settings.profiles.current_printer(), self.OctoprintPrinterProfile, position.get_position()) position.update(Commands.parse("M83")) position.update(Commands.parse("G0 e1.1")) self.assertEqual(position.e(), 1.1) self.assertEqual(position.e_relative_pos(previous_pos), -1.1) # move and test previous_pos = Pos(self.Settings.profiles.current_printer(), self.OctoprintPrinterProfile, position.get_position()) position.update(Commands.parse("G0 e1.1")) self.assertEqual(position.e(), 2.2) self.assertEqual(position.e_relative_pos(previous_pos), -1.1) # move and test previous_pos = Pos(self.Settings.profiles.current_printer(), self.OctoprintPrinterProfile, position.get_position()) position.update(Commands.parse("G0 e-2.2")) self.assertEqual(position.e(), 0) self.assertEqual(position.e_relative_pos(previous_pos), 2.2)
def test_zHop(self): """Test zHop detection.""" # set zhop distance self.Settings.profiles.current_printer().z_hop = .5 position = Position(self.Settings, self.OctoprintPrinterProfile, False) # test initial state self.assertFalse(position.is_zhop()) # check without homed axis position.update(Commands.parse("G1 x0 y0 z0")) self.assertFalse(position.is_zhop()) position.update(Commands.parse("G1 x0 y0 z0.5")) self.assertFalse(position.is_zhop()) # set relative extruder, absolute xyz, home axis, check again position.update(Commands.parse("M83")) position.update(Commands.parse("G90")) position.update(Commands.parse("G28")) self.assertFalse(position.is_zhop()) # Position reports as NotHomed (misnomer, need to replace), needs to get # coordinates position.update(Commands.parse("G1 x0 y0 z0")) # Move up without extrude, this is not a zhop since we haven't extruded # anything! position.update(Commands.parse("g0 z0.5")) self.assertFalse(position.is_zhop()) # move back down to 0 and extrude position.update(Commands.parse("g0 z0 e1")) self.assertFalse(position.is_zhop()) # Move up without extrude, this should trigger zhop start position.update(Commands.parse("g0 z0.5")) self.assertTrue(position.is_zhop()) # move below zhop threshold position.update(Commands.parse("g0 z0.3")) self.assertFalse(position.is_zhop()) # move right up to zhop without going over, we are within the rounding error position.update(Commands.parse("g0 z0.4999")) self.assertTrue(position.is_zhop()) # Extrude on z5 position.update(Commands.parse("g0 z0.5 e1")) self.assertFalse(position.is_zhop()) # partial z lift, , we are within the rounding error position.update(Commands.parse("g0 z0.9999")) self.assertTrue(position.is_zhop()) # Still hopped! position.update(Commands.parse("g0 z1")) self.assertTrue(position.is_zhop()) # test with extrusion start at 1.5 position.update(Commands.parse("g0 z1.5 e1")) self.assertFalse(position.is_zhop()) # test with extrusion at 2 position.update(Commands.parse("g0 z2 e1")) self.assertFalse(position.is_zhop()) # zhop position.update(Commands.parse("g0 z2.5 e0")) self.assertTrue(position.is_zhop()) position.update(Commands.parse("no-command")) self.assertTrue(position.is_zhop())
def test_unknown_word(self): gcode = "K100" parsed = Commands.parse(gcode) self.assertIsNone(parsed.cmd) self.assertIsNone(parsed.parameters)
def test_Home(self): """Test the home command. Make sure the position is set to 0,0,0 after the home.""" position = Position(self.Settings, self.OctoprintPrinterProfile, False) position.update(Commands.parse("G28")) self.assertEqual(position.x(), 0) self.assertTrue(position.get_position().XHomed) self.assertEqual(position.y(), 0) self.assertTrue(position.get_position().YHomed) self.assertEqual(position.z(), 0) self.assertTrue(position.get_position().ZHomed) self.assertTrue(position.has_homed_axes()) position = Position(self.Settings, self.OctoprintPrinterProfile, False) position.update(Commands.parse("G28 X")) self.assertEqual(position.x(), 0) self.assertTrue(position.get_position().XHomed) self.assertIsNone(position.y()) self.assertFalse(position.get_position().YHomed) self.assertIsNone(position.z()) self.assertFalse(position.get_position().ZHomed) self.assertFalse(position.has_homed_axes()) position = Position(self.Settings, self.OctoprintPrinterProfile, False) position.update(Commands.parse("G28 Y")) self.assertIsNone(position.x()) self.assertFalse(position.get_position().XHomed) self.assertEqual(position.y(), 0) self.assertTrue(position.get_position().YHomed) self.assertIsNone(position.z()) self.assertFalse(position.get_position().ZHomed) self.assertFalse(position.has_homed_axes()) position = Position(self.Settings, self.OctoprintPrinterProfile, False) position.update(Commands.parse("G28 Z")) self.assertIsNone(position.x()) self.assertFalse(position.get_position().XHomed) self.assertIsNone(position.y()) self.assertFalse(position.get_position().YHomed) self.assertEqual(position.z(), 0) self.assertTrue(position.get_position().ZHomed) self.assertFalse(position.has_homed_axes()) position = Position(self.Settings, self.OctoprintPrinterProfile, False) position.update(Commands.parse("G28 Z X Y")) self.assertEqual(position.x(), 0) self.assertTrue(position.get_position().XHomed) self.assertEqual(position.y(), 0) self.assertTrue(position.get_position().YHomed) self.assertEqual(position.z(), 0) self.assertTrue(position.get_position().ZHomed) self.assertTrue(position.has_homed_axes()) position = Position(self.Settings, self.OctoprintPrinterProfile, False) position.update(Commands.parse("g28")) position.update(Commands.parse("g1 x0 y0 z0")) # here we have seen the upded coordinates, but we do not know the position self.assertEqual(position.x(), 0) self.assertTrue(position.get_position().XHomed) self.assertEqual(position.y(), 0) self.assertTrue(position.get_position().YHomed) self.assertEqual(position.z(), 0) self.assertTrue(position.get_position().ZHomed) # give it another position, now we have homed axis with a known position position.update(Commands.parse("g1 x0 y0 z0")) self.assertEqual(position.x(), 0) self.assertTrue(position.get_position().XHomed) self.assertEqual(position.y(), 0) self.assertTrue(position.get_position().YHomed) self.assertEqual(position.z(), 0) self.assertTrue(position.get_position().ZHomed) self.assertTrue(position.has_homed_axes())