mirror of
https://github.com/sinseman44/PyCNC.git
synced 2026-07-16 08:37:09 +00:00
circular interpolation
This commit is contained in:
@@ -139,4 +139,4 @@ class TestCoordinates(unittest.TestCase):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
unittest.main()
|
||||
|
||||
+22
-2
@@ -91,14 +91,34 @@ class TestGMachine(unittest.TestCase):
|
||||
m.do_command, GCode.parse_line("G2X4Y4I2J2"))
|
||||
self.assertRaises(GMachineException,
|
||||
m.do_command, GCode.parse_line("G3X4Y4I2J2"))
|
||||
m.do_command(GCode.parse_line("G17"))
|
||||
m.do_command(GCode.parse_line("G1X1"))
|
||||
m.do_command(GCode.parse_line("G2J1"))
|
||||
m.do_command(GCode.parse_line("G3J1"))
|
||||
self.assertEqual(m.position(), Coordinates(1, 0, 0, 0))
|
||||
m.do_command(GCode.parse_line("G1X5Y5"))
|
||||
m.do_command(GCode.parse_line("G1X10Y10"))
|
||||
m.do_command(GCode.parse_line("G2X9I1"))
|
||||
self.assertEqual(m.position(), Coordinates(9, 10, 0, 0))
|
||||
m.do_command(GCode.parse_line("G19"))
|
||||
m.do_command(GCode.parse_line("G1X10Y10Z10"))
|
||||
m.do_command(GCode.parse_line("G3Y8K1"))
|
||||
self.assertEqual(m.position(), Coordinates(10, 8, 10, 0))
|
||||
m.do_command(GCode.parse_line("G17"))
|
||||
m.do_command(GCode.parse_line("G1X5Y5Z0"))
|
||||
m.do_command(GCode.parse_line("G2X0Y0Z5I-2J-2"))
|
||||
self.assertEqual(m.position(), Coordinates(0, 0, 5, 0))
|
||||
|
||||
m.do_command(GCode.parse_line("G17"))
|
||||
m.do_command(GCode.parse_line("G1X90Y90"))
|
||||
m.do_command(GCode.parse_line("G2X90Y70I-5J-5"))
|
||||
self.assertEqual(m.position(), Coordinates(90, 70, 5, 0))
|
||||
m.do_command(GCode.parse_line("G18"))
|
||||
m.do_command(GCode.parse_line("G1X90Y90Z20E0"))
|
||||
m.do_command(GCode.parse_line("G2Z20X70I-5K-5E22"))
|
||||
self.assertEqual(m.position(), Coordinates(70, 90, 20, 22))
|
||||
m.do_command(GCode.parse_line("G19"))
|
||||
m.do_command(GCode.parse_line("G1X90Y90Z20"))
|
||||
m.do_command(GCode.parse_line("G2Y90Z0J-5K-5E27"))
|
||||
self.assertEqual(m.position(), Coordinates(90, 90, 0, 27))
|
||||
|
||||
def test_g4(self):
|
||||
m = GMachine()
|
||||
|
||||
+139
-10
@@ -19,8 +19,17 @@ class TestPulses(unittest.TestCase):
|
||||
self.assertRaises(ZeroDivisionError,
|
||||
PulseGeneratorLinear,
|
||||
Coordinates(0, 0, 0, 0), self.v)
|
||||
self.assertRaises(ZeroDivisionError, PulseGeneratorCircular,
|
||||
Coordinates(0, 0, 0, 0), Coordinates(0, 0, 9, 9),
|
||||
PLANE_XY, CW, self.v)
|
||||
self.assertRaises(ZeroDivisionError, PulseGeneratorCircular,
|
||||
Coordinates(0, 0, 0, 0), Coordinates(9, 0, 0, 9),
|
||||
PLANE_YZ, CW, self.v)
|
||||
self.assertRaises(ZeroDivisionError, PulseGeneratorCircular,
|
||||
Coordinates(0, 0, 0, 0), Coordinates(0, 9, 0, 9),
|
||||
PLANE_ZX, CW, self.v)
|
||||
|
||||
def test_step(self):
|
||||
def test_step_linear(self):
|
||||
# Check if PulseGenerator returns correctly single step movement.
|
||||
g = PulseGeneratorLinear(Coordinates(1.0 / STEPPER_PULSES_PER_MM_X,
|
||||
0, 0, 0),
|
||||
@@ -52,19 +61,121 @@ class TestPulses(unittest.TestCase):
|
||||
self.assertEqual(pe, 0)
|
||||
self.assertEqual(i, 1)
|
||||
|
||||
def test_linear_with_hal_virtual(self):
|
||||
|
||||
def __check_circular(self, delta, radius, plane, direction = CW):
|
||||
g = PulseGeneratorCircular(delta, radius, plane, direction, self.v)
|
||||
x, y, z, e = 0, 0, 0, 0
|
||||
dx, dy, dz, de = None, None, None, None
|
||||
dir_changed = 0
|
||||
dir_requested = False
|
||||
t = -1
|
||||
for dir, px, py, pz, pe in g:
|
||||
if dir:
|
||||
dx, dy, dz, de = px, py, pz, pe
|
||||
dir_requested = True
|
||||
continue
|
||||
if dir_requested: # ignore last change
|
||||
dir_requested = False
|
||||
dir_changed += 1
|
||||
if px is not None:
|
||||
x += dx
|
||||
if py is not None:
|
||||
y += dy
|
||||
if pz is not None:
|
||||
z += dz
|
||||
if pe is not None:
|
||||
e += de
|
||||
v = list(i for i in (px, py, pz, pe) if i is not None)
|
||||
self.assertEqual(min(v), max(v))
|
||||
self.assertLessEqual(t, min(v))
|
||||
t = max(v)
|
||||
return dir_changed, Coordinates(x / STEPPER_PULSES_PER_MM_X,
|
||||
y / STEPPER_PULSES_PER_MM_Y,
|
||||
z / STEPPER_PULSES_PER_MM_Z,
|
||||
e / STEPPER_PULSES_PER_MM_E)
|
||||
|
||||
def test_single_radius_circles(self):
|
||||
# Check if PulseGenerator returns correctly single radius movement in
|
||||
# both direction.
|
||||
_, pos = self.__check_circular(Coordinates(0, 0, 0, 0),
|
||||
Coordinates(1.0 / STEPPER_PULSES_PER_MM_X, 0, 0, 0),
|
||||
PLANE_XY, CW)
|
||||
self.assertEqual(pos, Coordinates(0, 0, 0, 0))
|
||||
_, pos = self.__check_circular(Coordinates(0, 0, 0, 0),
|
||||
Coordinates(-1.0 / STEPPER_PULSES_PER_MM_X, 0, 0, 0),
|
||||
PLANE_XY, CW)
|
||||
self.assertEqual(pos, Coordinates(0, 0, 0, 0))
|
||||
_, pos = self.__check_circular(Coordinates(0, 0, 0, 0),
|
||||
Coordinates(0, 1.0 / STEPPER_PULSES_PER_MM_Y, 0, 0),
|
||||
PLANE_YZ, CW)
|
||||
self.assertEqual(pos, Coordinates(0, 0, 0, 0))
|
||||
_, pos = self.__check_circular(Coordinates(0, 0, 0, 0),
|
||||
Coordinates(0, -1.0 / STEPPER_PULSES_PER_MM_Y, 0, 0),
|
||||
PLANE_YZ, CW)
|
||||
self.assertEqual(pos, Coordinates(0, 0, 0, 0))
|
||||
_, pos = self.__check_circular(Coordinates(0, 0, 0, 0),
|
||||
Coordinates(0, 0, 1.0 / STEPPER_PULSES_PER_MM_Z, 0),
|
||||
PLANE_ZX, CW)
|
||||
self.assertEqual(pos, Coordinates(0, 0, 0, 0))
|
||||
_, pos = self.__check_circular(Coordinates(0, 0, 0, 0),
|
||||
Coordinates(0, 0, -1.0 / STEPPER_PULSES_PER_MM_Z, 0),
|
||||
PLANE_ZX, CW)
|
||||
self.assertEqual(pos, Coordinates(0, 0, 0, 0))
|
||||
_, pos = self.__check_circular(Coordinates(0, 0, 0, 0),
|
||||
Coordinates(1.0 / STEPPER_PULSES_PER_MM_X, 0, 0, 0),
|
||||
PLANE_XY, CCW)
|
||||
self.assertEqual(pos, Coordinates(0, 0, 0, 0))
|
||||
_, pos = self.__check_circular(Coordinates(0, 0, 0, 0),
|
||||
Coordinates(-1.0 / STEPPER_PULSES_PER_MM_X, 0, 0, 0),
|
||||
PLANE_XY, CCW)
|
||||
self.assertEqual(pos, Coordinates(0, 0, 0, 0))
|
||||
_, pos = self.__check_circular(Coordinates(0, 0, 0, 0),
|
||||
Coordinates(0, 1.0 / STEPPER_PULSES_PER_MM_Y, 0, 0),
|
||||
PLANE_YZ, CCW)
|
||||
self.assertEqual(pos, Coordinates(0, 0, 0, 0))
|
||||
_, pos = self.__check_circular(Coordinates(0, 0, 0, 0),
|
||||
Coordinates(0, -1.0 / STEPPER_PULSES_PER_MM_Y, 0, 0),
|
||||
PLANE_YZ, CCW)
|
||||
self.assertEqual(pos, Coordinates(0, 0, 0, 0))
|
||||
_, pos = self.__check_circular(Coordinates(0, 0, 0, 0),
|
||||
Coordinates(0, 0, 1.0 / STEPPER_PULSES_PER_MM_Z, 0),
|
||||
PLANE_ZX, CCW)
|
||||
self.assertEqual(pos, Coordinates(0, 0, 0, 0))
|
||||
_, pos = self.__check_circular(Coordinates(0, 0, 0, 0),
|
||||
Coordinates(0, 0, -1.0 / STEPPER_PULSES_PER_MM_Z, 0),
|
||||
PLANE_ZX, CCW)
|
||||
self.assertEqual(pos, Coordinates(0, 0, 0, 0))
|
||||
|
||||
def test_with_hal_virtual(self):
|
||||
# Using hal_virtual module for this test, it already contains plenty
|
||||
# of asserts for wrong number of pulses, pulse timing issues etc
|
||||
hal_virtual.move_linear(Coordinates(1, 0, 0, 0), self.v)
|
||||
hal_virtual.move_linear(Coordinates(25.4, 0, 0, 0), self.v)
|
||||
hal_virtual.move_linear(Coordinates(25.4, 0, 0, 0), self.v)
|
||||
hal_virtual.move_linear(Coordinates(25.4, 0, 0, 0), self.v)
|
||||
hal_virtual.move_linear(Coordinates(TABLE_SIZE_X_MM,
|
||||
hal_virtual.move(PulseGeneratorLinear(Coordinates(1, 0, 0, 0),
|
||||
self.v))
|
||||
hal_virtual.move(PulseGeneratorLinear(Coordinates(25.4, 0, 0, 0),
|
||||
self.v))
|
||||
hal_virtual.move(PulseGeneratorLinear(Coordinates(25.4, 0, 0, 0),
|
||||
self.v))
|
||||
hal_virtual.move(PulseGeneratorLinear(Coordinates(25.4, 0, 0, 0),
|
||||
self.v))
|
||||
hal_virtual.move(PulseGeneratorLinear(Coordinates(TABLE_SIZE_X_MM,
|
||||
TABLE_SIZE_Y_MM,
|
||||
TABLE_SIZE_Z_MM,
|
||||
100.0), self.v)
|
||||
100.0), self.v))
|
||||
hal_virtual.move(PulseGeneratorCircular(Coordinates(0, 20, 0, 0),
|
||||
Coordinates(-10, 10, 0, 0),
|
||||
PLANE_XY, CW, self.v))
|
||||
hal_virtual.move(PulseGeneratorCircular(Coordinates(-4, -4, 0, 0),
|
||||
Coordinates(-2, -2, 0, 0),
|
||||
PLANE_XY, CW, self.v))
|
||||
hal_virtual.move(PulseGeneratorCircular(Coordinates(- 2.0 / STEPPER_PULSES_PER_MM_X,
|
||||
- 2.0 / STEPPER_PULSES_PER_MM_Y,
|
||||
0, 0),
|
||||
Coordinates(- 1.0 / STEPPER_PULSES_PER_MM_X,
|
||||
- 1.0 / STEPPER_PULSES_PER_MM_Y,
|
||||
0, 0),
|
||||
PLANE_XY, CW, self.v))
|
||||
|
||||
def test_twice_faster(self):
|
||||
def test_twice_faster_linear(self):
|
||||
# Checks if one axis moves exactly twice faster, pulses are correct.
|
||||
m = Coordinates(2, 4, 0, 0)
|
||||
g = PulseGeneratorLinear(m, self.v)
|
||||
@@ -112,10 +223,23 @@ class TestPulses(unittest.TestCase):
|
||||
self.assertEqual(m.z * STEPPER_PULSES_PER_MM_Z, iz)
|
||||
self.assertEqual(m.e * STEPPER_PULSES_PER_MM_E, ie)
|
||||
self.assertLessEqual(t, g.total_time_s())
|
||||
_, pos = self.__check_circular(Coordinates(0, 8, 0, 7),
|
||||
Coordinates(1, 0, 1, 0),
|
||||
PLANE_ZX, CCW)
|
||||
self.assertEqual(pos, Coordinates(0, 8, 0, 7))
|
||||
_, pos = self.__check_circular(Coordinates(5, 0, 0, 6),
|
||||
Coordinates(0, 1, -1, 0),
|
||||
PLANE_YZ, CW)
|
||||
self.assertEqual(pos, Coordinates(5, 0, 0, 6))
|
||||
_, pos = self.__check_circular(Coordinates(-2, -2, 3, 2),
|
||||
Coordinates(-1, -1, 0, 0),
|
||||
PLANE_XY, CCW)
|
||||
self.assertEqual(pos, Coordinates(-2, -2, 3, 2))
|
||||
|
||||
def test_acceleration_velocity(self):
|
||||
# Check if acceleration present in pulses sequence and if velocity
|
||||
# is correct
|
||||
# is correct, since PulseGenerator is responsible for this, check only
|
||||
# one child class.
|
||||
m = Coordinates(TABLE_SIZE_X_MM, 0, 0, 0)
|
||||
g = PulseGeneratorLinear(m, self.v)
|
||||
i = 0
|
||||
@@ -156,6 +280,11 @@ class TestPulses(unittest.TestCase):
|
||||
dir_found = True
|
||||
# check dirs
|
||||
self.assertTrue(px < 0 and py > 0 and pz < 0 and pe > 0)
|
||||
# check for circle, full circle
|
||||
dir_changed, _ = self.__check_circular(Coordinates(0, 0, 0, 0),
|
||||
Coordinates(1.0, 1.0, 0, 0),
|
||||
PLANE_ZX, CCW)
|
||||
self.assertEqual(dir_changed, 4)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
Reference in New Issue
Block a user