mirror of
https://github.com/sinseman44/PyCNC.git
synced 2026-07-26 10:16:55 +00:00
migration to a new hardware, adding additional configs
This commit is contained in:
+17
-7
@@ -1,16 +1,26 @@
|
|||||||
# Hardware limitations config
|
# Hardware limitations config
|
||||||
STEPPER_PULSE_LENGTH_US = 2
|
STEPPER_PULSE_LENGTH_US = 2
|
||||||
STEPPER_MAX_VELOCITY_MM_PER_MIN = 1800 # mm per min
|
STEPPER_MAX_ACCELERATION_MM_PER_S2 = 3000 # for all axis, mm per sec^2
|
||||||
STEPPER_MAX_ACCELERATION_MM_PER_S2 = 200 # mm per sec^2
|
|
||||||
|
|
||||||
STEPPER_PULSES_PER_MM_X = 400
|
MAX_VELOCITY_MM_PER_MIN_X = 30000 # mm per min
|
||||||
STEPPER_PULSES_PER_MM_Y = 400
|
MAX_VELOCITY_MM_PER_MIN_Y = 24000 # mm per min
|
||||||
|
MAX_VELOCITY_MM_PER_MIN_Z = 120 # mm per min
|
||||||
|
MAX_VELOCITY_MM_PER_MIN_E = 1500 # mm per min
|
||||||
|
|
||||||
|
STEPPER_PULSES_PER_MM_X = 100
|
||||||
|
STEPPER_PULSES_PER_MM_Y = 100
|
||||||
STEPPER_PULSES_PER_MM_Z = 400
|
STEPPER_PULSES_PER_MM_Z = 400
|
||||||
STEPPER_PULSES_PER_MM_E = 80
|
STEPPER_PULSES_PER_MM_E = 150
|
||||||
|
|
||||||
|
# invert axises direction
|
||||||
|
STEPPER_INVERTED_X = True
|
||||||
|
STEPPER_INVERTED_Y = False
|
||||||
|
STEPPER_INVERTED_Z = False
|
||||||
|
STEPPER_INVERTED_E = True
|
||||||
|
|
||||||
TABLE_SIZE_X_MM = 200
|
TABLE_SIZE_X_MM = 200
|
||||||
TABLE_SIZE_Y_MM = 300
|
TABLE_SIZE_Y_MM = 200
|
||||||
TABLE_SIZE_Z_MM = 48
|
TABLE_SIZE_Z_MM = 220
|
||||||
|
|
||||||
SPINDLE_MAX_RPM = 10000
|
SPINDLE_MAX_RPM = 10000
|
||||||
EXTRUDER_MAX_TEMPERATURE = 250
|
EXTRUDER_MAX_TEMPERATURE = 250
|
||||||
|
|||||||
+56
-15
@@ -25,7 +25,6 @@ class GMachine(object):
|
|||||||
# init variables
|
# init variables
|
||||||
self._velocity = 0
|
self._velocity = 0
|
||||||
self._spindle_rpm = 0
|
self._spindle_rpm = 0
|
||||||
self._pause = 0
|
|
||||||
self._local = None
|
self._local = None
|
||||||
self._convertCoordinates = 0
|
self._convertCoordinates = 0
|
||||||
self._absoluteCoordinates = 0
|
self._absoluteCoordinates = 0
|
||||||
@@ -47,9 +46,11 @@ class GMachine(object):
|
|||||||
def reset(self):
|
def reset(self):
|
||||||
""" Reinitialize all program configurable thing.
|
""" Reinitialize all program configurable thing.
|
||||||
"""
|
"""
|
||||||
self._velocity = 1000
|
self._velocity = min(MAX_VELOCITY_MM_PER_MIN_X,
|
||||||
|
MAX_VELOCITY_MM_PER_MIN_Y,
|
||||||
|
MAX_VELOCITY_MM_PER_MIN_Z,
|
||||||
|
MAX_VELOCITY_MM_PER_MIN_E)
|
||||||
self._spindle_rpm = 1000
|
self._spindle_rpm = 1000
|
||||||
self._pause = 0
|
|
||||||
self._local = Coordinates(0.0, 0.0, 0.0, 0.0)
|
self._local = Coordinates(0.0, 0.0, 0.0, 0.0)
|
||||||
self._convertCoordinates = 1.0
|
self._convertCoordinates = 1.0
|
||||||
self._absoluteCoordinates = True
|
self._absoluteCoordinates = True
|
||||||
@@ -96,6 +97,14 @@ class GMachine(object):
|
|||||||
TABLE_SIZE_Z_MM, 0)):
|
TABLE_SIZE_Z_MM, 0)):
|
||||||
raise GMachineException("out of effective area")
|
raise GMachineException("out of effective area")
|
||||||
|
|
||||||
|
# noinspection PyMethodMayBeStatic
|
||||||
|
def __check_velocity(self, max_velocity):
|
||||||
|
if max_velocity.x > MAX_VELOCITY_MM_PER_MIN_X \
|
||||||
|
or max_velocity.y > MAX_VELOCITY_MM_PER_MIN_Y \
|
||||||
|
or max_velocity.z > MAX_VELOCITY_MM_PER_MIN_Z \
|
||||||
|
or max_velocity.e > MAX_VELOCITY_MM_PER_MIN_E:
|
||||||
|
raise GMachineException("out of maximum speed")
|
||||||
|
|
||||||
def _move_linear(self, delta, velocity):
|
def _move_linear(self, delta, velocity):
|
||||||
delta = delta.round(1.0 / STEPPER_PULSES_PER_MM_X,
|
delta = delta.round(1.0 / STEPPER_PULSES_PER_MM_X,
|
||||||
1.0 / STEPPER_PULSES_PER_MM_Y,
|
1.0 / STEPPER_PULSES_PER_MM_Y,
|
||||||
@@ -103,10 +112,12 @@ class GMachine(object):
|
|||||||
1.0 / STEPPER_PULSES_PER_MM_E)
|
1.0 / STEPPER_PULSES_PER_MM_E)
|
||||||
if delta.is_zero():
|
if delta.is_zero():
|
||||||
return
|
return
|
||||||
|
velocity_per_axis = abs(delta) * (velocity / delta.length())
|
||||||
self.__check_delta(delta)
|
self.__check_delta(delta)
|
||||||
|
|
||||||
logging.info("Moving linearly {}".format(delta))
|
logging.info("Moving linearly {}".format(delta))
|
||||||
gen = PulseGeneratorLinear(delta, velocity)
|
gen = PulseGeneratorLinear(delta, velocity)
|
||||||
|
self.__check_velocity(gen.max_velocity())
|
||||||
hal.move(gen)
|
hal.move(gen)
|
||||||
# save position
|
# save position
|
||||||
self._position = self._position + delta
|
self._position = self._position + delta
|
||||||
@@ -212,14 +223,19 @@ class GMachine(object):
|
|||||||
direction, radius, velocity))
|
direction, radius, velocity))
|
||||||
gen = PulseGeneratorCircular(circle_end, radius, self._plane, direction,
|
gen = PulseGeneratorCircular(circle_end, radius, self._plane, direction,
|
||||||
velocity)
|
velocity)
|
||||||
hal.move(gen)
|
self.__check_velocity(gen.max_velocity())
|
||||||
# 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
|
||||||
|
linear_gen = None
|
||||||
if not linear_delta.is_zero():
|
if not linear_delta.is_zero():
|
||||||
logging.info("Moving additionally {} to finish circle command".
|
logging.info("Moving additionally {} to finish circle command".
|
||||||
format(linear_delta))
|
format(linear_delta))
|
||||||
gen = PulseGeneratorLinear(linear_delta, velocity)
|
linear_gen = PulseGeneratorLinear(linear_delta, velocity)
|
||||||
hal.move(gen)
|
self.__check_velocity(linear_gen.max_velocity())
|
||||||
|
# do movements
|
||||||
|
hal.move(gen)
|
||||||
|
if linear_gen is not None:
|
||||||
|
hal.move(linear_gen)
|
||||||
# save position
|
# save position
|
||||||
self._position = self._position + circle_end + linear_delta
|
self._position = self._position + circle_end + linear_delta
|
||||||
|
|
||||||
@@ -227,9 +243,10 @@ class GMachine(object):
|
|||||||
""" Move head to park position
|
""" Move head to park position
|
||||||
"""
|
"""
|
||||||
d = Coordinates(0, 0, -self._position.z, 0)
|
d = Coordinates(0, 0, -self._position.z, 0)
|
||||||
self._move_linear(d, STEPPER_MAX_VELOCITY_MM_PER_MIN)
|
self._move_linear(d, MAX_VELOCITY_MM_PER_MIN_Z)
|
||||||
d = Coordinates(-self._position.x, -self._position.y, 0, 0)
|
d = Coordinates(-self._position.x, -self._position.y, 0, 0)
|
||||||
self._move_linear(d, STEPPER_MAX_VELOCITY_MM_PER_MIN)
|
self._move_linear(d, min(MAX_VELOCITY_MM_PER_MIN_X,
|
||||||
|
MAX_VELOCITY_MM_PER_MIN_Y))
|
||||||
|
|
||||||
def position(self):
|
def position(self):
|
||||||
""" Return current machine position (after the latest command)
|
""" Return current machine position (after the latest command)
|
||||||
@@ -294,17 +311,37 @@ class GMachine(object):
|
|||||||
self._convertCoordinates)
|
self._convertCoordinates)
|
||||||
# coord = self._position + delta
|
# coord = self._position + delta
|
||||||
velocity = gcode.get('F', self._velocity)
|
velocity = gcode.get('F', self._velocity)
|
||||||
pause = gcode.get('P', self._pause)
|
|
||||||
radius = gcode.radius(Coordinates(0.0, 0.0, 0.0, 0.0),
|
radius = gcode.radius(Coordinates(0.0, 0.0, 0.0, 0.0),
|
||||||
self._convertCoordinates)
|
self._convertCoordinates)
|
||||||
# check parameters
|
# check parameters
|
||||||
if velocity <= 0 or velocity > STEPPER_MAX_VELOCITY_MM_PER_MIN:
|
if velocity <= 0:
|
||||||
raise GMachineException("bad feed speed")
|
raise GMachineException("negative feed speed")
|
||||||
if pause < 0:
|
|
||||||
raise GMachineException("bad delay")
|
|
||||||
# select command and run it
|
# select command and run it
|
||||||
if c == 'G0': # rapid move
|
if c == 'G0': # rapid move
|
||||||
self._move_linear(delta, STEPPER_MAX_VELOCITY_MM_PER_MIN)
|
vl = max(MAX_VELOCITY_MM_PER_MIN_X,
|
||||||
|
MAX_VELOCITY_MM_PER_MIN_Y,
|
||||||
|
MAX_VELOCITY_MM_PER_MIN_Z,
|
||||||
|
MAX_VELOCITY_MM_PER_MIN_E)
|
||||||
|
l = delta.length()
|
||||||
|
if l > 0:
|
||||||
|
proportion = abs(delta) / l
|
||||||
|
if proportion.x > 0:
|
||||||
|
v = MAX_VELOCITY_MM_PER_MIN_X / proportion.x
|
||||||
|
if v < vl:
|
||||||
|
vl = v
|
||||||
|
if proportion.y > 0:
|
||||||
|
v = MAX_VELOCITY_MM_PER_MIN_Y / proportion.y
|
||||||
|
if v < vl:
|
||||||
|
vl = v
|
||||||
|
if proportion.z > 0:
|
||||||
|
v = MAX_VELOCITY_MM_PER_MIN_Z / proportion.z
|
||||||
|
if v < vl:
|
||||||
|
vl = v
|
||||||
|
if proportion.e > 0:
|
||||||
|
v = MAX_VELOCITY_MM_PER_MIN_E / proportion.e
|
||||||
|
if v < vl:
|
||||||
|
vl = v
|
||||||
|
self._move_linear(delta, vl)
|
||||||
elif c == 'G1': # linear interpolation
|
elif c == 'G1': # linear interpolation
|
||||||
self._move_linear(delta, velocity)
|
self._move_linear(delta, velocity)
|
||||||
elif c == 'G2': # circular interpolation, clockwise
|
elif c == 'G2': # circular interpolation, clockwise
|
||||||
@@ -312,6 +349,11 @@ class GMachine(object):
|
|||||||
elif c == 'G3': # circular interpolation, counterclockwise
|
elif c == 'G3': # circular interpolation, counterclockwise
|
||||||
self._circular(delta, radius, velocity, CCW)
|
self._circular(delta, radius, velocity, CCW)
|
||||||
elif c == 'G4': # delay in s
|
elif c == 'G4': # delay in s
|
||||||
|
if not gcode.has('P'):
|
||||||
|
raise GMachineException("P is not specified")
|
||||||
|
pause = gcode.get('P', 0)
|
||||||
|
if pause < 0:
|
||||||
|
raise GMachineException("bad delay")
|
||||||
hal.join()
|
hal.join()
|
||||||
time.sleep(pause)
|
time.sleep(pause)
|
||||||
elif c == 'G17': # XY plane select
|
elif c == 'G17': # XY plane select
|
||||||
@@ -394,6 +436,5 @@ class GMachine(object):
|
|||||||
raise GMachineException("unknown command")
|
raise GMachineException("unknown command")
|
||||||
# save parameters on success
|
# save parameters on success
|
||||||
self._velocity = velocity
|
self._velocity = velocity
|
||||||
self._pause = pause
|
|
||||||
logging.debug("position {}".format(self._position))
|
logging.debug("position {}".format(self._position))
|
||||||
return answer
|
return answer
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ def init():
|
|||||||
gpio.clear(BED_HEATER_PIN)
|
gpio.clear(BED_HEATER_PIN)
|
||||||
|
|
||||||
# calibration
|
# calibration
|
||||||
|
# TODO remove this from hal and rewrite, check if there is a special g
|
||||||
|
# command for this
|
||||||
gpio.set(STEPPER_DIR_PIN_X)
|
gpio.set(STEPPER_DIR_PIN_X)
|
||||||
gpio.set(STEPPER_DIR_PIN_Y)
|
gpio.set(STEPPER_DIR_PIN_Y)
|
||||||
gpio.set(STEPPER_DIR_PIN_Z)
|
gpio.set(STEPPER_DIR_PIN_Z)
|
||||||
@@ -73,7 +75,10 @@ def init():
|
|||||||
break
|
break
|
||||||
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) / (min(MAX_VELOCITY_MM_PER_MIN_X,
|
||||||
|
MAX_VELOCITY_MM_PER_MIN_Y,
|
||||||
|
MAX_VELOCITY_MM_PER_MIN_Z,
|
||||||
|
MAX_VELOCITY_MM_PER_MIN_E)
|
||||||
/ 60 * max(STEPPER_PULSES_PER_MM_X,
|
/ 60 * max(STEPPER_PULSES_PER_MM_X,
|
||||||
STEPPER_PULSES_PER_MM_Y,
|
STEPPER_PULSES_PER_MM_Y,
|
||||||
STEPPER_PULSES_PER_MM_Z)))
|
STEPPER_PULSES_PER_MM_Z)))
|
||||||
|
|||||||
+19
-11
@@ -74,22 +74,30 @@ def move(generator):
|
|||||||
dx, dy, dz, de = 0, 0, 0, 0
|
dx, dy, dz, de = 0, 0, 0, 0
|
||||||
mx, my, mz, me = 0, 0, 0, 0
|
mx, my, mz, me = 0, 0, 0, 0
|
||||||
cx, cy, cz, ce = 0, 0, 0, 0
|
cx, cy, cz, ce = 0, 0, 0, 0
|
||||||
direction_x, direction_y, direction_z, dire = 1, 1, 1, 1
|
direction_x, direction_y, direction_z, direction_e = 1, 1, 1, 1
|
||||||
st = time.time()
|
st = time.time()
|
||||||
direction_found = False
|
direction_found = False
|
||||||
for direction, tx, ty, tz, te in generator:
|
for direction, tx, ty, tz, te in generator:
|
||||||
if direction:
|
if direction:
|
||||||
direction_found = True
|
direction_found = True
|
||||||
direction_x, direction_y, direction_z, dire = tx, ty, tz, te
|
direction_x, direction_y, direction_z, direction_e = tx, ty, tz, te
|
||||||
|
if STEPPER_INVERTED_X:
|
||||||
|
direction_x = -direction_x
|
||||||
|
if STEPPER_INVERTED_Y:
|
||||||
|
direction_y = -direction_y
|
||||||
|
if STEPPER_INVERTED_Z:
|
||||||
|
direction_z = -direction_z
|
||||||
|
if STEPPER_INVERTED_E:
|
||||||
|
direction_e = -direction_e
|
||||||
if isinstance(generator, PulseGeneratorLinear):
|
if isinstance(generator, PulseGeneratorLinear):
|
||||||
assert ((tx < 0 and delta.x < 0) or (tx > 0 and delta.x > 0)
|
assert ((direction_x < 0 and delta.x < 0)
|
||||||
or delta.x == 0)
|
or (direction_x > 0 and delta.x > 0) or delta.x == 0)
|
||||||
assert ((ty < 0 and delta.y < 0) or (ty > 0 and delta.y > 0)
|
assert ((direction_y < 0 and delta.y < 0)
|
||||||
or delta.y == 0)
|
or (direction_y > 0 and delta.y > 0) or delta.y == 0)
|
||||||
assert ((tz < 0 and delta.z < 0) or (tz > 0 and delta.z > 0)
|
assert ((direction_z < 0 and delta.z < 0)
|
||||||
or delta.z == 0)
|
or (direction_z > 0 and delta.z > 0) or delta.z == 0)
|
||||||
assert ((te < 0 and delta.e < 0) or (te > 0 and delta.e > 0)
|
assert ((direction_e < 0 and delta.e < 0)
|
||||||
or delta.e == 0)
|
or (direction_e > 0 and delta.e > 0) or delta.e == 0)
|
||||||
continue
|
continue
|
||||||
if tx is not None:
|
if tx is not None:
|
||||||
if tx > mx:
|
if tx > mx:
|
||||||
@@ -131,7 +139,7 @@ def move(generator):
|
|||||||
if te > me:
|
if te > me:
|
||||||
me = te
|
me = te
|
||||||
te = int(round(te * 1000000))
|
te = int(round(te * 1000000))
|
||||||
ie += dire
|
ie += direction_e
|
||||||
ce += 1
|
ce += 1
|
||||||
if le is not None:
|
if le is not None:
|
||||||
de = te - le
|
de = te - le
|
||||||
|
|||||||
+42
-10
@@ -86,7 +86,7 @@ class PulseGenerator(object):
|
|||||||
(self._acceleration_time_s, self._linear_time_s,
|
(self._acceleration_time_s, self._linear_time_s,
|
||||||
max_axis_velocity_mm_per_sec) = self._get_movement_parameters()
|
max_axis_velocity_mm_per_sec) = self._get_movement_parameters()
|
||||||
# helper variable
|
# helper variable
|
||||||
self._2Vmax_per_a = (2.0 * max_axis_velocity_mm_per_sec
|
self._2Vmax_per_a = (2.0 * max_axis_velocity_mm_per_sec.find_max()
|
||||||
/ STEPPER_MAX_ACCELERATION_MM_PER_S2)
|
/ STEPPER_MAX_ACCELERATION_MM_PER_S2)
|
||||||
self._iteration_x = 0
|
self._iteration_x = 0
|
||||||
self._iteration_y = 0
|
self._iteration_y = 0
|
||||||
@@ -152,7 +152,16 @@ class PulseGenerator(object):
|
|||||||
# check if direction update:
|
# check if direction update:
|
||||||
if direction != self._iteration_direction:
|
if direction != self._iteration_direction:
|
||||||
self._iteration_direction = direction
|
self._iteration_direction = direction
|
||||||
return (True,) + direction
|
dir_x, dir_y, dir_z, dir_e = direction
|
||||||
|
if STEPPER_INVERTED_X:
|
||||||
|
dir_x = -dir_x
|
||||||
|
if STEPPER_INVERTED_Y:
|
||||||
|
dir_y = -dir_y
|
||||||
|
if STEPPER_INVERTED_Z:
|
||||||
|
dir_z = -dir_z
|
||||||
|
if STEPPER_INVERTED_E:
|
||||||
|
dir_e = -dir_e
|
||||||
|
return True, dir_x, dir_y, dir_z, dir_e
|
||||||
# check condition to stop
|
# check condition to stop
|
||||||
if tx is None and ty is None and tz is None and te is None:
|
if tx is None and ty is None and tz is None and te is None:
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
@@ -204,6 +213,13 @@ class PulseGenerator(object):
|
|||||||
"""
|
"""
|
||||||
return self._delta
|
return self._delta
|
||||||
|
|
||||||
|
def max_velocity(self):
|
||||||
|
""" Get max velocity for each axis.
|
||||||
|
:return: Vector with max velocity(in mm per min) for each axis.
|
||||||
|
"""
|
||||||
|
_, _, v = self._get_movement_parameters()
|
||||||
|
return v * SECONDS_IN_MINUTE
|
||||||
|
|
||||||
|
|
||||||
class PulseGeneratorLinear(PulseGenerator):
|
class PulseGeneratorLinear(PulseGenerator):
|
||||||
def __init__(self, delta_mm, velocity_mm_per_min):
|
def __init__(self, delta_mm, velocity_mm_per_min):
|
||||||
@@ -253,7 +269,7 @@ class PulseGeneratorLinear(PulseGenerator):
|
|||||||
"""
|
"""
|
||||||
return (self.acceleration_time_s,
|
return (self.acceleration_time_s,
|
||||||
self.linear_time_s,
|
self.linear_time_s,
|
||||||
self.max_velocity_mm_per_sec.find_max())
|
self.max_velocity_mm_per_sec)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def __linear(i, pulses_per_mm, total_pulses, velocity_mm_per_sec):
|
def __linear(i, pulses_per_mm, total_pulses, velocity_mm_per_sec):
|
||||||
@@ -431,8 +447,10 @@ class PulseGeneratorCircular(PulseGenerator):
|
|||||||
self._iterations_a += round(radius * apm)
|
self._iterations_a += round(radius * apm)
|
||||||
self._iterations_b += round(radius * bpm)
|
self._iterations_b += round(radius * bpm)
|
||||||
if direction == CCW:
|
if direction == CCW:
|
||||||
self._iterations_a = 4 * round(radius * apm) - self._iterations_a
|
self._iterations_a = (4 * round(radius * apm)
|
||||||
self._iterations_b = 4 * round(radius * bpm) - self._iterations_b
|
- self._iterations_a)
|
||||||
|
self._iterations_b = (4 * round(radius * bpm)
|
||||||
|
- self._iterations_b)
|
||||||
|
|
||||||
arc = delta_angle * radius
|
arc = delta_angle * radius
|
||||||
e2 = delta.e * delta.e
|
e2 = delta.e * delta.e
|
||||||
@@ -472,19 +490,33 @@ class PulseGeneratorCircular(PulseGenerator):
|
|||||||
self._e_velocity = abs(delta.e) / l * velocity
|
self._e_velocity = abs(delta.e) / l * velocity
|
||||||
self._r_div_v = radius / circular_velocity
|
self._r_div_v = radius / circular_velocity
|
||||||
self._e_dir = math.copysign(1, delta.e)
|
self._e_dir = math.copysign(1, delta.e)
|
||||||
self.max_velocity_mm_per_sec = max(circular_velocity,
|
if self._plane == PLANE_XY:
|
||||||
self._velocity_3rd, self._e_velocity)
|
self.max_velocity_mm_per_sec = Coordinates(circular_velocity,
|
||||||
self.acceleration_time_s = (self.max_velocity_mm_per_sec
|
circular_velocity,
|
||||||
|
self._velocity_3rd,
|
||||||
|
self._e_velocity)
|
||||||
|
elif self._plane == PLANE_YZ:
|
||||||
|
self.max_velocity_mm_per_sec = Coordinates(self._velocity_3rd,
|
||||||
|
circular_velocity,
|
||||||
|
circular_velocity,
|
||||||
|
self._e_velocity)
|
||||||
|
elif self._plane == PLANE_ZX:
|
||||||
|
self.max_velocity_mm_per_sec = Coordinates(circular_velocity,
|
||||||
|
self._velocity_3rd,
|
||||||
|
circular_velocity,
|
||||||
|
self._e_velocity)
|
||||||
|
self.acceleration_time_s = (self.max_velocity_mm_per_sec.find_max()
|
||||||
/ STEPPER_MAX_ACCELERATION_MM_PER_S2)
|
/ STEPPER_MAX_ACCELERATION_MM_PER_S2)
|
||||||
if l == 0:
|
if l == 0:
|
||||||
self.linear_time_s = 0.0
|
self.linear_time_s = 0.0
|
||||||
self.max_velocity_mm_per_sec = 0
|
self.max_velocity_mm_per_sec = Coordinates(0, 0, 0, 0)
|
||||||
elif STEPPER_MAX_ACCELERATION_MM_PER_S2 * self.acceleration_time_s \
|
elif STEPPER_MAX_ACCELERATION_MM_PER_S2 * self.acceleration_time_s \
|
||||||
** 2 > l:
|
** 2 > l:
|
||||||
self.acceleration_time_s = \
|
self.acceleration_time_s = \
|
||||||
math.sqrt(l / STEPPER_MAX_ACCELERATION_MM_PER_S2)
|
math.sqrt(l / STEPPER_MAX_ACCELERATION_MM_PER_S2)
|
||||||
self.linear_time_s = 0.0
|
self.linear_time_s = 0.0
|
||||||
self.max_velocity_mm_per_sec = l / self.acceleration_time_s
|
v = l / self.acceleration_time_s
|
||||||
|
self.max_velocity_mm_per_sec = Coordinates(v, v, v, v)
|
||||||
else:
|
else:
|
||||||
linear_distance_mm = l - self.acceleration_time_s ** 2 \
|
linear_distance_mm = l - self.acceleration_time_s ** 2 \
|
||||||
* STEPPER_MAX_ACCELERATION_MM_PER_S2
|
* STEPPER_MAX_ACCELERATION_MM_PER_S2
|
||||||
|
|||||||
+4
-3
@@ -7,10 +7,11 @@ G3 X110 Y110 I-5 J-5 ; full circle in one move
|
|||||||
G2 X90 Y90 I-10 J-10 ; second half of circle
|
G2 X90 Y90 I-10 J-10 ; second half of circle
|
||||||
G2 X90 Y70 I-10 J-10 ; quarter of circle
|
G2 X90 Y70 I-10 J-10 ; quarter of circle
|
||||||
G2 X90 Y90 I-10 J10 ; three quoter circle
|
G2 X90 Y90 I-10 J10 ; three quoter circle
|
||||||
G3 X90 Y90 Z 20 I-10 J-10 ; spiral
|
G3 X90 Y90 Z 20 I-10 J-10 F1000 ; spiral
|
||||||
|
f1800
|
||||||
G2 X92.07 Y85 I-5 J-5 ; small arc
|
G2 X92.07 Y85 I-5 J-5 ; small arc
|
||||||
G2 X90 Y90 I-7.07 J0; more then 270 degree arc
|
G2 X90 Y90 I-7.07 J0; more then 270 degree arc
|
||||||
G18
|
G18
|
||||||
G2 X90 Y90 K-5
|
G2 X90 Y90 K-5 F120
|
||||||
G19
|
G19
|
||||||
G2 X90 Y90 K-5
|
G2 X90 Y90 K-5 F120
|
||||||
|
|||||||
+2
-1
@@ -2,7 +2,8 @@ g21
|
|||||||
g90
|
g90
|
||||||
; move to start position
|
; move to start position
|
||||||
g1x50y50f1800
|
g1x50y50f1800
|
||||||
z20
|
z20f120
|
||||||
|
f1800
|
||||||
g91
|
g91
|
||||||
; run
|
; run
|
||||||
x100
|
x100
|
||||||
|
|||||||
+22
-1
@@ -63,7 +63,7 @@ class TestGMachine(unittest.TestCase):
|
|||||||
self.assertRaises(GMachineException,
|
self.assertRaises(GMachineException,
|
||||||
m.do_command, GCode.parse_line("G1F-1"))
|
m.do_command, GCode.parse_line("G1F-1"))
|
||||||
self.assertRaises(GMachineException,
|
self.assertRaises(GMachineException,
|
||||||
m.do_command, GCode.parse_line("G1F999999"))
|
m.do_command, GCode.parse_line("G1X100F999999"))
|
||||||
self.assertRaises(GMachineException,
|
self.assertRaises(GMachineException,
|
||||||
m.do_command, GCode.parse_line("G1X-1Y0Z0"))
|
m.do_command, GCode.parse_line("G1X-1Y0Z0"))
|
||||||
self.assertRaises(GMachineException,
|
self.assertRaises(GMachineException,
|
||||||
@@ -71,6 +71,27 @@ class TestGMachine(unittest.TestCase):
|
|||||||
self.assertRaises(GMachineException,
|
self.assertRaises(GMachineException,
|
||||||
m.do_command, GCode.parse_line("G1X0Y0Z-1"))
|
m.do_command, GCode.parse_line("G1X0Y0Z-1"))
|
||||||
|
|
||||||
|
def test_feed_rate(self):
|
||||||
|
m = GMachine()
|
||||||
|
self.assertRaises(GMachineException,
|
||||||
|
m.do_command, GCode.parse_line("G1X1F-1"))
|
||||||
|
m.do_command(GCode.parse_line("G1X100F"
|
||||||
|
+ str(MAX_VELOCITY_MM_PER_MIN_X)))
|
||||||
|
m.do_command(GCode.parse_line("G1Y100F"
|
||||||
|
+ str(MAX_VELOCITY_MM_PER_MIN_Y)))
|
||||||
|
m.do_command(GCode.parse_line("G1Z100F"
|
||||||
|
+ str(MAX_VELOCITY_MM_PER_MIN_Z)))
|
||||||
|
m.do_command(GCode.parse_line("G1E100F"
|
||||||
|
+ str(MAX_VELOCITY_MM_PER_MIN_E)))
|
||||||
|
s = "G1X0F" + str(MAX_VELOCITY_MM_PER_MIN_X + 1)
|
||||||
|
self.assertRaises(GMachineException, m.do_command, GCode.parse_line(s))
|
||||||
|
s = "G1Y0F" + str(MAX_VELOCITY_MM_PER_MIN_Y + 1)
|
||||||
|
self.assertRaises(GMachineException, m.do_command, GCode.parse_line(s))
|
||||||
|
s = "G1Z0F" + str(MAX_VELOCITY_MM_PER_MIN_Z + 1)
|
||||||
|
self.assertRaises(GMachineException, m.do_command, GCode.parse_line(s))
|
||||||
|
s = "G1E0F" + str(MAX_VELOCITY_MM_PER_MIN_E + 1)
|
||||||
|
self.assertRaises(GMachineException, m.do_command, GCode.parse_line(s))
|
||||||
|
|
||||||
def test_g2_g3(self):
|
def test_g2_g3(self):
|
||||||
m = GMachine()
|
m = GMachine()
|
||||||
self.assertRaises(GMachineException,
|
self.assertRaises(GMachineException,
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ g21
|
|||||||
g1y1
|
g1y1
|
||||||
g1y-1
|
g1y-1
|
||||||
g90
|
g90
|
||||||
g92x100y100z100
|
g92x100y100z100f240
|
||||||
m111
|
m111
|
||||||
g1x98y98z98
|
g1x98y98z98f120
|
||||||
(head should be in zero position, and last movement with 500 mm/min velocity)
|
(head should be in zero position)
|
||||||
m2
|
m2
|
||||||
|
|||||||
+31
-4
@@ -8,7 +8,10 @@ from cnc import hal_virtual
|
|||||||
|
|
||||||
class TestPulses(unittest.TestCase):
|
class TestPulses(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.v = STEPPER_MAX_VELOCITY_MM_PER_MIN
|
self.v = min(MAX_VELOCITY_MM_PER_MIN_X,
|
||||||
|
MAX_VELOCITY_MM_PER_MIN_Y,
|
||||||
|
MAX_VELOCITY_MM_PER_MIN_Z,
|
||||||
|
MAX_VELOCITY_MM_PER_MIN_E)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
pass
|
pass
|
||||||
@@ -70,6 +73,14 @@ class TestPulses(unittest.TestCase):
|
|||||||
for direction_i, px, py, pz, pe in g:
|
for direction_i, px, py, pz, pe in g:
|
||||||
if direction_i:
|
if direction_i:
|
||||||
dx, dy, dz, de = px, py, pz, pe
|
dx, dy, dz, de = px, py, pz, pe
|
||||||
|
if STEPPER_INVERTED_X:
|
||||||
|
dx = -dx
|
||||||
|
if STEPPER_INVERTED_Y:
|
||||||
|
dy = -dy
|
||||||
|
if STEPPER_INVERTED_Z:
|
||||||
|
dz = -dz
|
||||||
|
if STEPPER_INVERTED_E:
|
||||||
|
de = -de
|
||||||
dir_requested = True
|
dir_requested = True
|
||||||
continue
|
continue
|
||||||
if dir_requested: # ignore last change
|
if dir_requested: # ignore last change
|
||||||
@@ -235,7 +246,8 @@ class TestPulses(unittest.TestCase):
|
|||||||
# is correct, since PulseGenerator is responsible for this, check only
|
# is correct, since PulseGenerator is responsible for this, check only
|
||||||
# one child class.
|
# one child class.
|
||||||
m = Coordinates(TABLE_SIZE_X_MM, 0, 0, 0)
|
m = Coordinates(TABLE_SIZE_X_MM, 0, 0, 0)
|
||||||
g = PulseGeneratorLinear(m, self.v)
|
velocity = 1000
|
||||||
|
g = PulseGeneratorLinear(m, velocity)
|
||||||
i = 0
|
i = 0
|
||||||
lx = 0
|
lx = 0
|
||||||
lt, at, bt = None, None, None
|
lt, at, bt = None, None, None
|
||||||
@@ -249,8 +261,7 @@ class TestPulses(unittest.TestCase):
|
|||||||
bt = px - lx
|
bt = px - lx
|
||||||
lx = px
|
lx = px
|
||||||
i += 1
|
i += 1
|
||||||
self.assertEqual(round(60.0 / lt / STEPPER_PULSES_PER_MM_X),
|
self.assertEqual(round(60.0 / lt / STEPPER_PULSES_PER_MM_X), velocity)
|
||||||
round(self.v))
|
|
||||||
self.assertGreater(at, lt)
|
self.assertGreater(at, lt)
|
||||||
self.assertGreater(bt, lt)
|
self.assertGreater(bt, lt)
|
||||||
|
|
||||||
@@ -261,6 +272,14 @@ class TestPulses(unittest.TestCase):
|
|||||||
dir_found = False
|
dir_found = False
|
||||||
for direction, px, py, pz, pe in g:
|
for direction, px, py, pz, pe in g:
|
||||||
if direction:
|
if direction:
|
||||||
|
if STEPPER_INVERTED_X:
|
||||||
|
px = -px
|
||||||
|
if STEPPER_INVERTED_Y:
|
||||||
|
py = -py
|
||||||
|
if STEPPER_INVERTED_Z:
|
||||||
|
pz = -pz
|
||||||
|
if STEPPER_INVERTED_E:
|
||||||
|
pe = -pe
|
||||||
# should be once
|
# should be once
|
||||||
self.assertFalse(dir_found)
|
self.assertFalse(dir_found)
|
||||||
dir_found = True
|
dir_found = True
|
||||||
@@ -271,6 +290,14 @@ class TestPulses(unittest.TestCase):
|
|||||||
dir_found = False
|
dir_found = False
|
||||||
for direction, px, py, pz, pe in g:
|
for direction, px, py, pz, pe in g:
|
||||||
if direction:
|
if direction:
|
||||||
|
if STEPPER_INVERTED_X:
|
||||||
|
px = -px
|
||||||
|
if STEPPER_INVERTED_Y:
|
||||||
|
py = -py
|
||||||
|
if STEPPER_INVERTED_Z:
|
||||||
|
pz = -pz
|
||||||
|
if STEPPER_INVERTED_E:
|
||||||
|
pe = -pe
|
||||||
# should be once
|
# should be once
|
||||||
self.assertFalse(dir_found)
|
self.assertFalse(dir_found)
|
||||||
dir_found = True
|
dir_found = True
|
||||||
|
|||||||
Reference in New Issue
Block a user