mirror of
https://github.com/sinseman44/PyCNC.git
synced 2026-07-26 10:16:55 +00:00
performance optimization
This commit is contained in:
@@ -145,8 +145,11 @@ def move(generator):
|
|||||||
dma.add_set_clear(pins_to_set, pins_to_clear)
|
dma.add_set_clear(pins_to_set, pins_to_clear)
|
||||||
continue
|
continue
|
||||||
pins = 0
|
pins = 0
|
||||||
k = int(round(min(x for x in (tx, ty, tz, te) if x is not None)
|
m = None
|
||||||
* US_IN_SECONDS))
|
for i in (tx, ty, tz, te):
|
||||||
|
if i is not None and (m is None or i < m):
|
||||||
|
m = i
|
||||||
|
k = int(round(m * US_IN_SECONDS))
|
||||||
if tx is not None:
|
if tx is not None:
|
||||||
pins |= STEP_PIN_MASK_X
|
pins |= STEP_PIN_MASK_X
|
||||||
if ty is not None:
|
if ty is not None:
|
||||||
|
|||||||
+43
-42
@@ -28,10 +28,8 @@ class PulseGenerator(object):
|
|||||||
brake will take and recalculate time for them. Linear part will be as
|
brake will take and recalculate time for them. Linear part will be as
|
||||||
is. Since maximum velocity and acceleration is always the same, there
|
is. Since maximum velocity and acceleration is always the same, there
|
||||||
is the ACCELERATION_FACTOR_PER_SEC variable.
|
is the ACCELERATION_FACTOR_PER_SEC variable.
|
||||||
In the same way round or other interpolation can be implemented based on
|
In the same way circular or other interpolation can be implemented
|
||||||
this class.
|
based this class.
|
||||||
Note: round interpolation would require direction change during movement.
|
|
||||||
It's not implemented yet.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, delta):
|
def __init__(self, delta):
|
||||||
@@ -162,7 +160,10 @@ class PulseGenerator(object):
|
|||||||
raise StopIteration
|
raise StopIteration
|
||||||
|
|
||||||
# convert to real time
|
# convert to real time
|
||||||
m = min(x for x in (tx, ty, tz, te) if x is not None)
|
m = None
|
||||||
|
for i in (tx, ty, tz, te):
|
||||||
|
if i is not None and (m is None or i < m):
|
||||||
|
m = i
|
||||||
am = self._to_accelerated_time(m)
|
am = self._to_accelerated_time(m)
|
||||||
# sort pulses in time
|
# sort pulses in time
|
||||||
if tx is not None:
|
if tx is not None:
|
||||||
@@ -326,13 +327,15 @@ class PulseGeneratorCircular(PulseGenerator):
|
|||||||
apm = STEPPER_PULSES_PER_MM_Z
|
apm = STEPPER_PULSES_PER_MM_Z
|
||||||
bpm = STEPPER_PULSES_PER_MM_X
|
bpm = STEPPER_PULSES_PER_MM_X
|
||||||
# adjust radius to fit into axises step.
|
# adjust radius to fit into axises step.
|
||||||
self._radius = round(math.sqrt(sa * sa + sb * sb) * min(apm, bpm)) \
|
radius = round(math.sqrt(sa * sa + sb * sb) * min(apm, bpm)) \
|
||||||
/ min(apm, bpm)
|
/ min(apm, bpm)
|
||||||
self._radius2 = self._radius * self._radius
|
self._radius2 = radius * radius
|
||||||
self._start_a = sa
|
self._radius_a_pulses = int(radius * apm)
|
||||||
self._start_b = sb
|
self._radius_b_pulses = int(radius * bpm)
|
||||||
|
self._start_a_pulses = int(sa * apm)
|
||||||
|
self._start_b_pulses = int(sb * bpm)
|
||||||
assert round(math.sqrt(ea * ea + eb * eb) * min(apm, bpm)) \
|
assert round(math.sqrt(ea * ea + eb * eb) * min(apm, bpm)) \
|
||||||
/ min(apm, bpm) == self._radius, "Wrong end point"
|
/ min(apm, bpm) == radius, "Wrong end point"
|
||||||
|
|
||||||
# Calculate angles and directions.
|
# Calculate angles and directions.
|
||||||
start_angle = self.__angle(sa, sb)
|
start_angle = self.__angle(sa, sb)
|
||||||
@@ -360,8 +363,8 @@ class PulseGeneratorCircular(PulseGenerator):
|
|||||||
self._dir_a = -1
|
self._dir_a = -1
|
||||||
else:
|
else:
|
||||||
self._dir_a = 1
|
self._dir_a = 1
|
||||||
self._side_a = self._start_b < 0 or (self._start_b == 0 and self._dir_b < 0)
|
self._side_a = self._start_b_pulses < 0 or (self._start_b_pulses == 0 and self._dir_b < 0)
|
||||||
self._side_b = self._start_a < 0 or (self._start_a == 0 and self._dir_a < 0)
|
self._side_b = self._start_a_pulses < 0 or (self._start_a_pulses == 0 and self._dir_a < 0)
|
||||||
self._start_angle = start_angle
|
self._start_angle = start_angle
|
||||||
logging.debug("start angle {}, end angle {}, delta {}".format(
|
logging.debug("start angle {}, end angle {}, delta {}".format(
|
||||||
start_angle * 180.0 / math.pi,
|
start_angle * 180.0 / math.pi,
|
||||||
@@ -381,8 +384,8 @@ class PulseGeneratorCircular(PulseGenerator):
|
|||||||
rstart = int(start_angle / (math.pi / 2.0))
|
rstart = int(start_angle / (math.pi / 2.0))
|
||||||
rend = int(end_angle_m / (math.pi / 2.0))
|
rend = int(end_angle_m / (math.pi / 2.0))
|
||||||
if rend - rstart >= 4:
|
if rend - rstart >= 4:
|
||||||
self._iterations_a = 4 * int(self._radius * apm)
|
self._iterations_a = 4 * int(radius * apm)
|
||||||
self._iterations_b = 4 * int(self._radius * apm)
|
self._iterations_b = 4 * int(radius * apm)
|
||||||
else:
|
else:
|
||||||
if rstart == rend:
|
if rstart == rend:
|
||||||
self._iterations_a = int(abs(sa - ea) * apm)
|
self._iterations_a = int(abs(sa - ea) * apm)
|
||||||
@@ -394,30 +397,30 @@ class PulseGeneratorCircular(PulseGenerator):
|
|||||||
i -= 4
|
i -= 4
|
||||||
if r == rstart:
|
if r == rstart:
|
||||||
if i == 0 or i == 2:
|
if i == 0 or i == 2:
|
||||||
self._iterations_a += int(self._radius * apm) - int(abs(sa) * apm)
|
self._iterations_a += int(radius * apm) - int(abs(sa) * apm)
|
||||||
else:
|
else:
|
||||||
self._iterations_a += int(abs(sa) * apm)
|
self._iterations_a += int(abs(sa) * apm)
|
||||||
if i == 1 or i == 3:
|
if i == 1 or i == 3:
|
||||||
self._iterations_b += int(self._radius * bpm) - int(abs(sb) * bpm)
|
self._iterations_b += int(radius * bpm) - int(abs(sb) * bpm)
|
||||||
else:
|
else:
|
||||||
self._iterations_b += int(abs(sb) * bpm)
|
self._iterations_b += int(abs(sb) * bpm)
|
||||||
elif r == rend:
|
elif r == rend:
|
||||||
if i == 0 or i == 2:
|
if i == 0 or i == 2:
|
||||||
self._iterations_a += int(abs(ea) * apm)
|
self._iterations_a += int(abs(ea) * apm)
|
||||||
else:
|
else:
|
||||||
self._iterations_a += int(self._radius * apm) - int(abs(ea) * apm)
|
self._iterations_a += int(radius * apm) - int(abs(ea) * apm)
|
||||||
if i == 1 or i == 3:
|
if i == 1 or i == 3:
|
||||||
self._iterations_b += int(abs(eb) * bpm)
|
self._iterations_b += int(abs(eb) * bpm)
|
||||||
else:
|
else:
|
||||||
self._iterations_b += int(self._radius * bpm) - int(abs(eb) * bpm)
|
self._iterations_b += int(radius * bpm) - int(abs(eb) * bpm)
|
||||||
else:
|
else:
|
||||||
self._iterations_a += int(self._radius * apm)
|
self._iterations_a += int(radius * apm)
|
||||||
self._iterations_b += int(self._radius * bpm)
|
self._iterations_b += int(radius * bpm)
|
||||||
if direction == CCW:
|
if direction == CCW:
|
||||||
self._iterations_a = 4 * int(self._radius * apm) - self._iterations_a
|
self._iterations_a = 4 * int(radius * apm) - self._iterations_a
|
||||||
self._iterations_b = 4 * int(self._radius * bpm) - self._iterations_b
|
self._iterations_b = 4 * int(radius * bpm) - self._iterations_b
|
||||||
|
|
||||||
arc = delta_angle * self._radius
|
arc = delta_angle * radius
|
||||||
e2 = delta.e * delta.e
|
e2 = delta.e * delta.e
|
||||||
if self._plane == PLANE_XY:
|
if self._plane == PLANE_XY:
|
||||||
self._iterations_3rd = abs(delta.z) * STEPPER_PULSES_PER_MM_Z
|
self._iterations_3rd = abs(delta.z) * STEPPER_PULSES_PER_MM_Z
|
||||||
@@ -437,7 +440,7 @@ class PulseGeneratorCircular(PulseGenerator):
|
|||||||
self._iterations_e = abs(delta.e) * STEPPER_PULSES_PER_MM_E
|
self._iterations_e = abs(delta.e) * STEPPER_PULSES_PER_MM_E
|
||||||
# Velocity splits with corresponding distance.
|
# Velocity splits with corresponding distance.
|
||||||
cV = arc / l * velocity
|
cV = arc / l * velocity
|
||||||
self._RdivV = self._radius / cV
|
self._RdivV = radius / cV
|
||||||
self._e_velocity = abs(delta.e) / l * velocity
|
self._e_velocity = abs(delta.e) / l * velocity
|
||||||
self._e_dir = math.copysign(1, delta.e)
|
self._e_dir = math.copysign(1, delta.e)
|
||||||
self.max_velocity_mm_per_sec = max(cV, self._velocity_3rd,
|
self.max_velocity_mm_per_sec = max(cV, self._velocity_3rd,
|
||||||
@@ -469,22 +472,18 @@ class PulseGeneratorCircular(PulseGenerator):
|
|||||||
self.linear_time_s, \
|
self.linear_time_s, \
|
||||||
self.max_velocity_mm_per_sec
|
self.max_velocity_mm_per_sec
|
||||||
|
|
||||||
def __circularHelper(self, start, i, pulses_per_mm, side, dir):
|
def __circularHelper(self, start, i, radius, side, dir):
|
||||||
np = start + dir * i / pulses_per_mm
|
np = start + dir * i
|
||||||
np = round(np, 10)
|
if np > radius:
|
||||||
if np > self._radius:
|
np -= 2 * (np - radius)
|
||||||
np -= 2 * (np - self._radius)
|
|
||||||
np = round(np, 10)
|
|
||||||
dir = -dir
|
dir = -dir
|
||||||
side = not side
|
side = not side
|
||||||
if np < -self._radius:
|
if np < -radius:
|
||||||
np -= 2 * (np + self._radius)
|
np -= 2 * (np + radius)
|
||||||
np = round(np, 10)
|
|
||||||
dir = -dir
|
dir = -dir
|
||||||
side = not side
|
side = not side
|
||||||
if np > self._radius:
|
if np > radius:
|
||||||
np -= 2 * (np - self._radius)
|
np -= 2 * (np - radius)
|
||||||
np = round(np, 10)
|
|
||||||
dir = -dir
|
dir = -dir
|
||||||
side = not side
|
side = not side
|
||||||
return np, dir, side
|
return np, dir, side
|
||||||
@@ -502,9 +501,10 @@ class PulseGeneratorCircular(PulseGenerator):
|
|||||||
def __circularA(self, i, pulses_per_mm):
|
def __circularA(self, i, pulses_per_mm):
|
||||||
if i >= self._iterations_a:
|
if i >= self._iterations_a:
|
||||||
return self._dir_a, None
|
return self._dir_a, None
|
||||||
a, dir, side = self.__circularHelper(self._start_a, i + 1,
|
a, dir, side = self.__circularHelper(self._start_a_pulses, i + 1,
|
||||||
pulses_per_mm, self._side_a,
|
self._radius_a_pulses,
|
||||||
self._dir_a)
|
self._side_a, self._dir_a)
|
||||||
|
a /= pulses_per_mm
|
||||||
# last item can be slightly more then end angle due to float precision
|
# last item can be slightly more then end angle due to float precision
|
||||||
if i + 1 == self._iterations_a:
|
if i + 1 == self._iterations_a:
|
||||||
return dir, self._RdivV * self._delta_angle
|
return dir, self._RdivV * self._delta_angle
|
||||||
@@ -516,9 +516,10 @@ class PulseGeneratorCircular(PulseGenerator):
|
|||||||
def __circularB(self, i, pulses_per_mm):
|
def __circularB(self, i, pulses_per_mm):
|
||||||
if i >= self._iterations_b:
|
if i >= self._iterations_b:
|
||||||
return self._dir_b, None
|
return self._dir_b, None
|
||||||
b, dir, side = self.__circularHelper(self._start_b, i + 1,
|
b, dir, side = self.__circularHelper(self._start_b_pulses, i + 1,
|
||||||
pulses_per_mm, self._side_b,
|
self._radius_b_pulses,
|
||||||
self._dir_b)
|
self._side_b, self._dir_b)
|
||||||
|
b /= pulses_per_mm
|
||||||
# last item can be slightly more then end angle due to float precision
|
# last item can be slightly more then end angle due to float precision
|
||||||
if i + 1 == self._iterations_b:
|
if i + 1 == self._iterations_b:
|
||||||
return dir, self._RdivV * self._delta_angle
|
return dir, self._RdivV * self._delta_angle
|
||||||
|
|||||||
Reference in New Issue
Block a user