split pulses per mm parameter for each axis

This commit is contained in:
Nikolay Khabarov
2017-05-27 03:53:30 +03:00
parent 0de4f3dc00
commit 665ba2ad1e
8 changed files with 47 additions and 30 deletions
+4 -1
View File
@@ -2,7 +2,10 @@
STEPPER_PULSE_LINGTH_US = 2 STEPPER_PULSE_LINGTH_US = 2
STEPPER_MAX_VELOCITY_MM_PER_MIN = 1800 # mm per min STEPPER_MAX_VELOCITY_MM_PER_MIN = 1800 # mm per min
STEPPER_MAX_ACCELERATION_MM_PER_S2 = 200 # mm per sec^2 STEPPER_MAX_ACCELERATION_MM_PER_S2 = 200 # mm per sec^2
STEPPER_PULSES_PER_MM = 400
STEPPER_PULSES_PER_MM_X = 400
STEPPER_PULSES_PER_MM_Y = 400
STEPPER_PULSES_PER_MM_Z = 400
TABLE_SIZE_X_MM = 200 TABLE_SIZE_X_MM = 200
TABLE_SIZE_Y_MM = 300 TABLE_SIZE_Y_MM = 300
+7 -5
View File
@@ -44,14 +44,16 @@ class Coordinates(object):
""" """
return math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z) return math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
def round(self, base): def round(self, base_x, base_y, base_z):
""" Round values to specified base, ie 0.49 with base 0.25 will be 0.5. """ Round values to specified base, ie 0.49 with base 0.25 will be 0.5.
:param base: Base. :param base_x: Base for x axis.
:param base_y: Base for y axis.
:param base_z: Base for z axis.
:return: New rounded object. :return: New rounded object.
""" """
return Coordinates(round(self.x / base) * base, return Coordinates(round(self.x / base_x) * base_x,
round(self.y / base) * base, round(self.y / base_y) * base_y,
round(self.z / base) * base) round(self.z / base_z) * base_z)
def find_max(self): def find_max(self):
""" Find a maximum value of all values. """ Find a maximum value of all values.
+9 -3
View File
@@ -65,7 +65,9 @@ class GMachine(object):
raise GMachineException("out of effective area") raise GMachineException("out of effective area")
def _move_linear(self, delta, velocity): def _move_linear(self, delta, velocity):
delta = delta.round(1.0 / STEPPER_PULSES_PER_MM) delta = delta.round(1.0 / STEPPER_PULSES_PER_MM_X,
1.0 / STEPPER_PULSES_PER_MM_Y,
1.0 / STEPPER_PULSES_PER_MM_Z)
if delta.is_zero(): if delta.is_zero():
return return
self.__check_delta(delta) self.__check_delta(delta)
@@ -126,7 +128,9 @@ class GMachine(object):
return ea, eb return ea, eb
def _circular(self, delta, radius, velocity, direction): def _circular(self, delta, radius, velocity, direction):
delta = delta.round(1.0 / STEPPER_PULSES_PER_MM) delta = delta.round(1.0 / STEPPER_PULSES_PER_MM_X,
1.0 / STEPPER_PULSES_PER_MM_Y,
1.0 / STEPPER_PULSES_PER_MM_Z)
self.__check_delta(delta) self.__check_delta(delta)
# get delta vector and put it on circle # get delta vector and put it on circle
circle_end = Coordinates(0,0,0) circle_end = Coordinates(0,0,0)
@@ -148,7 +152,9 @@ class GMachine(object):
self._position.z, self._position.x, self._position.z, self._position.x,
TABLE_SIZE_Z_MM, TABLE_SIZE_X_MM) TABLE_SIZE_Z_MM, TABLE_SIZE_X_MM)
circle_end.y = delta.y circle_end.y = delta.y
circle_end = circle_end.round(1.0 / STEPPER_PULSES_PER_MM) circle_end = circle_end.round(1.0 / STEPPER_PULSES_PER_MM_X,
1.0 / STEPPER_PULSES_PER_MM_Y,
1.0 / STEPPER_PULSES_PER_MM_Z)
hal.move_circular(circle_end, radius, self._plane, velocity, direction) hal.move_circular(circle_end, radius, self._plane, velocity, direction)
# if finish coords is not on circle, move some distance linearly # if finish coords is not on circle, move some distance linearly
linear_delta = delta - circle_end linear_delta = delta - circle_end
+9 -3
View File
@@ -52,8 +52,12 @@ def init():
dma.clear() dma.clear()
dma.add_pulse(pins, STEPPER_PULSE_LINGTH_US) dma.add_pulse(pins, STEPPER_PULSE_LINGTH_US)
st = time.time() st = time.time()
max_pulses_left = int(1.2 * STEPPER_PULSES_PER_MM * max( max_pulses_left = int(1.2 * max(STEPPER_PULSES_PER_MM_X,
TABLE_SIZE_X_MM, TABLE_SIZE_Y_MM, TABLE_SIZE_Z_MM)) STEPPER_PULSES_PER_MM_Y,
STEPPER_PULSES_PER_MM_Z) *
max(TABLE_SIZE_X_MM,
TABLE_SIZE_Y_MM,
TABLE_SIZE_Z_MM))
try: try:
while max_pulses_left > 0: while max_pulses_left > 0:
if (STEP_PIN_MASK_X & pins) != 0 and gpio.read(ENDSTOP_PIN_X) == 0: if (STEP_PIN_MASK_X & pins) != 0 and gpio.read(ENDSTOP_PIN_X) == 0:
@@ -73,7 +77,9 @@ def init():
dma.run(False) dma.run(False)
# limit velocity at ~10% of top velocity # limit velocity at ~10% of top velocity
time.sleep((1 / 0.10) / (STEPPER_MAX_VELOCITY_MM_PER_MIN time.sleep((1 / 0.10) / (STEPPER_MAX_VELOCITY_MM_PER_MIN
/ 60 * STEPPER_PULSES_PER_MM)) / 60 * max(STEPPER_PULSES_PER_MM_X,
STEPPER_PULSES_PER_MM_Y,
STEPPER_PULSES_PER_MM_Z)))
max_pulses_left -= 1 max_pulses_left -= 1
if st is not None: if st is not None:
if time.time() - st > 2: if time.time() - st > 2:
+3 -3
View File
@@ -76,9 +76,9 @@ def move_linear(delta, velocity):
f = list(x for x in (tx, ty, tz) if x is not None) f = list(x for x in (tx, ty, tz) if x is not None)
assert f.count(f[0]) == len(f), "fast forwarded pulse detected" assert f.count(f[0]) == len(f), "fast forwarded pulse detected"
pt = time.time() pt = time.time()
assert ix / STEPPER_PULSES_PER_MM == abs(delta.x), "x wrong number of pulses" assert ix / STEPPER_PULSES_PER_MM_X == abs(delta.x), "x wrong number of pulses"
assert iy / STEPPER_PULSES_PER_MM == abs(delta.y), "y wrong number of pulses" assert iy / STEPPER_PULSES_PER_MM_Y == abs(delta.y), "y wrong number of pulses"
assert iz / STEPPER_PULSES_PER_MM == abs(delta.z), "z wrong number of pulses" assert iz / STEPPER_PULSES_PER_MM_Z == abs(delta.z), "z wrong number of pulses"
assert max(mx, my, mz) <= generator.total_time_s(), "interpolation time or pulses wrong" assert max(mx, my, mz) <= generator.total_time_s(), "interpolation time or pulses wrong"
logging.debug("Did {}, {}, {} iterations".format(ix, iy, iz)) logging.debug("Did {}, {}, {} iterations".format(ix, iy, iz))
logging.info("prepared in " + str(round(pt - st, 2)) \ logging.info("prepared in " + str(round(pt - st, 2)) \
+3 -3
View File
@@ -216,10 +216,10 @@ class PulseGeneratorLinear(PulseGenerator):
""" Calculate interpolation values for linear movement, see super class """ Calculate interpolation values for linear movement, see super class
for details. for details.
""" """
t_x = self.__linear(ix / STEPPER_PULSES_PER_MM, self._distance_mm.x, t_x = self.__linear(ix / STEPPER_PULSES_PER_MM_X, self._distance_mm.x,
self.max_velocity_mm_per_sec.x) self.max_velocity_mm_per_sec.x)
t_y = self.__linear(iy / STEPPER_PULSES_PER_MM, self._distance_mm.y, t_y = self.__linear(iy / STEPPER_PULSES_PER_MM_Y, self._distance_mm.y,
self.max_velocity_mm_per_sec.y) self.max_velocity_mm_per_sec.y)
t_z = self.__linear(iz / STEPPER_PULSES_PER_MM, self._distance_mm.z, t_z = self.__linear(iz / STEPPER_PULSES_PER_MM_Z, self._distance_mm.z,
self.max_velocity_mm_per_sec.z) self.max_velocity_mm_per_sec.z)
return t_x, t_y, t_z return t_x, t_y, t_z
+2 -2
View File
@@ -53,11 +53,11 @@ class TestCoordinates(unittest.TestCase):
# round works in another way then Python's round. # round works in another way then Python's round.
# This round() rounds digits with specified step. # This round() rounds digits with specified step.
c = Coordinates(1.5, -1.4, 3.05) c = Coordinates(1.5, -1.4, 3.05)
r = c.round(1) r = c.round(1, 1, 1)
self.assertEqual(r.x, 2.0) self.assertEqual(r.x, 2.0)
self.assertEqual(r.y, -1.0) self.assertEqual(r.y, -1.0)
self.assertEqual(r.z, 3.0) self.assertEqual(r.z, 3.0)
r = c.round(0.25) r = c.round(0.25, 0.25, 0.25)
self.assertEqual(r.x, 1.5) self.assertEqual(r.x, 1.5)
self.assertEqual(r.y, -1.5) self.assertEqual(r.y, -1.5)
self.assertEqual(r.z, 3.0) self.assertEqual(r.z, 3.0)
+10 -10
View File
@@ -22,7 +22,7 @@ class TestPulses(unittest.TestCase):
def test_step(self): def test_step(self):
# Check if PulseGenerator returns correctly single step movement. # Check if PulseGenerator returns correctly single step movement.
g = PulseGeneratorLinear(Coordinates(1.0 / STEPPER_PULSES_PER_MM, 0, 0), g = PulseGeneratorLinear(Coordinates(1.0 / STEPPER_PULSES_PER_MM_X, 0, 0),
self.v) self.v)
i = 0 i = 0
for px, py, pz in g: for px, py, pz in g:
@@ -32,9 +32,9 @@ class TestPulses(unittest.TestCase):
self.assertEqual(pz, None) self.assertEqual(pz, None)
self.assertEqual(i, 1) self.assertEqual(i, 1)
g = PulseGeneratorLinear(Coordinates( g = PulseGeneratorLinear(Coordinates(
1.0 / STEPPER_PULSES_PER_MM, 1.0 / STEPPER_PULSES_PER_MM_X,
1.0 / STEPPER_PULSES_PER_MM, 1.0 / STEPPER_PULSES_PER_MM_Y,
1.0 / STEPPER_PULSES_PER_MM), 1.0 / STEPPER_PULSES_PER_MM_Z),
self.v) self.v)
i = 0 i = 0
for px, py, pz in g: for px, py, pz in g:
@@ -68,7 +68,7 @@ class TestPulses(unittest.TestCase):
self.assertNotEqual(py, None) self.assertNotEqual(py, None)
self.assertEqual(pz, None) self.assertEqual(pz, None)
i += 1 i += 1
self.assertEqual(m.find_max() * STEPPER_PULSES_PER_MM, i) self.assertEqual(m.find_max() * STEPPER_PULSES_PER_MM_Y, i)
def test_pulses_count_and_timings(self): def test_pulses_count_and_timings(self):
# Check if number of pulses is equal to specified distance. # Check if number of pulses is equal to specified distance.
@@ -89,9 +89,9 @@ class TestPulses(unittest.TestCase):
self.assertEqual(min(v), max(v)) self.assertEqual(min(v), max(v))
self.assertLess(t, min(v)) self.assertLess(t, min(v))
t = max(v) t = max(v)
self.assertEqual(m.x * STEPPER_PULSES_PER_MM, ix) self.assertEqual(m.x * STEPPER_PULSES_PER_MM_X, ix)
self.assertEqual(m.y * STEPPER_PULSES_PER_MM, iy) self.assertEqual(m.y * STEPPER_PULSES_PER_MM_Y, iy)
self.assertEqual(m.z * STEPPER_PULSES_PER_MM, iz) self.assertEqual(m.z * STEPPER_PULSES_PER_MM_Z, iz)
self.assertLessEqual(t, g.total_time_s()) self.assertLessEqual(t, g.total_time_s())
def test_acceleration_velocity(self): def test_acceleration_velocity(self):
@@ -104,12 +104,12 @@ class TestPulses(unittest.TestCase):
for px, py, pz in g: for px, py, pz in g:
if i == 2: if i == 2:
at = px - lx at = px - lx
if i == TABLE_SIZE_X_MM * STEPPER_PULSES_PER_MM / 2: if i == TABLE_SIZE_X_MM * STEPPER_PULSES_PER_MM_X / 2:
lt = px - lx lt = px - lx
bt = px - lx bt = px - lx
lx = px lx = px
i += 1 i += 1
self.assertEqual(round(60.0 / lt / STEPPER_PULSES_PER_MM), round(self.v)) self.assertEqual(round(60.0 / lt / STEPPER_PULSES_PER_MM_X), round(self.v))
self.assertGreater(at, lt) self.assertGreater(at, lt)
self.assertGreater(bt, lt) self.assertGreater(bt, lt)