-ish fini pour moi
This commit is contained in:
parent
f65b3ce532
commit
770100ef1c
2 changed files with 81 additions and 4 deletions
|
@ -6,6 +6,29 @@ import numpy as np
|
||||||
|
|
||||||
Point = NewType("point", List[float, float, float])
|
Point = NewType("point", List[float, float, float])
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyPep8Naming
|
||||||
|
def bezier_length(x0, y0, I, J, P, Q, X, Y, num_points=1000):
|
||||||
|
|
||||||
|
def dx(t):
|
||||||
|
return -3 * (1 - t)**2 * x0 + 3 * ((1 - t)**2 - 2 * t * (1 - t)) * (x0 + I) + 3 * (2 * t * (1 - t) - t**2) * (x0 + P) + 3 * t**2 * X
|
||||||
|
|
||||||
|
def dy(t):
|
||||||
|
return -3 * (1 - t)**2 * y0 + 3 * ((1 - t)**2 - 2 * t * (1 - t)) * (y0 + J) + 3 * (2 * t * (1 - t) - t**2) * (y0 + Q) + 3 * t**2 * Y
|
||||||
|
|
||||||
|
t_values = np.linspace(0, 1, num_points)
|
||||||
|
length = 0
|
||||||
|
|
||||||
|
for i in range(1, len(t_values)):
|
||||||
|
t1, t2 = t_values[i - 1], t_values[i]
|
||||||
|
dx1, dy1 = dx(t1), dy(t1)
|
||||||
|
dx2, dy2 = dx(t2), dy(t2)
|
||||||
|
segment_length = np.sqrt((dx1**2 + dy1**2) + (dx2**2 + dy2**2)) * (t2 - t1) / 2
|
||||||
|
length += segment_length
|
||||||
|
|
||||||
|
return length
|
||||||
|
|
||||||
|
|
||||||
# We will assume everything is up to documentation.
|
# We will assume everything is up to documentation.
|
||||||
class GCodeToMotors:
|
class GCodeToMotors:
|
||||||
# Hardcoded Values for Our Machine
|
# Hardcoded Values for Our Machine
|
||||||
|
@ -66,6 +89,10 @@ class GCodeToMotors:
|
||||||
feedrate: float = 0.
|
feedrate: float = 0.
|
||||||
feedrate_micros: int = 0
|
feedrate_micros: int = 0
|
||||||
|
|
||||||
|
is_g5_block: bool = False
|
||||||
|
prev_g5_p: float = 0.
|
||||||
|
prev_g5_q: float = 0.
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def to_steps(steps_per_unit: float, units: float) -> float:
|
def to_steps(steps_per_unit: float, units: float) -> float:
|
||||||
return steps_per_unit * units
|
return steps_per_unit * units
|
||||||
|
@ -205,7 +232,7 @@ class GCodeToMotors:
|
||||||
time.sleep(5e-6)
|
time.sleep(5e-6)
|
||||||
|
|
||||||
|
|
||||||
def instruction_to_velocities(self, instruction: str) -> Optional[List[float]]:
|
def instruction_converter(self, instruction: str) -> Optional[List[float]]:
|
||||||
if instruction[0] == "/":
|
if instruction[0] == "/":
|
||||||
return None
|
return None
|
||||||
fp: Point = [0., 0., 0.]
|
fp: Point = [0., 0., 0.]
|
||||||
|
@ -289,7 +316,7 @@ class GCodeToMotors:
|
||||||
step = step if (code == 3) else steps - step
|
step = step if (code == 3) else steps - step
|
||||||
newPoint[0] = center[0] + radius * np.cos(angleA + angle * (step / steps))
|
newPoint[0] = center[0] + radius * np.cos(angleA + angle * (step / steps))
|
||||||
newPoint[1] = center[1] + radius * np.sin(angleA + angle * (step / steps))
|
newPoint[1] = center[1] + radius * np.sin(angleA + angle * (step / steps))
|
||||||
self.set_position(newPoint[0], newPoint[1], fp[2])
|
self.set_target(newPoint[0], newPoint[1], fp[2])
|
||||||
|
|
||||||
if self.feedrate > 0:
|
if self.feedrate > 0:
|
||||||
self.feedrate_micros = self.calculate_feedrate_delay(self.feedrate)
|
self.feedrate_micros = self.calculate_feedrate_delay(self.feedrate)
|
||||||
|
@ -301,6 +328,54 @@ class GCodeToMotors:
|
||||||
case 4:
|
case 4:
|
||||||
time.sleep(search_string('P', instruction) * 1e-3)
|
time.sleep(search_string('P', instruction) * 1e-3)
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
if not self.is_g5_block:
|
||||||
|
control_1 = [0., 0., 0.]
|
||||||
|
control_1[0] = search_string('I', instruction) + self.current_units[0]
|
||||||
|
control_1[1] = search_string('J', instruction) + self.current_units[1]
|
||||||
|
|
||||||
|
else:
|
||||||
|
control_1 = [0., 0., 0.]
|
||||||
|
control_1[0] = -self.prev_g5_p + self.current_units[0]
|
||||||
|
control_1[1] = -self.prev_g5_q + self.current_units[1]
|
||||||
|
|
||||||
|
control_2 = [0., 0., 0.]
|
||||||
|
self.prev_g5_p = search_string('P', instruction)
|
||||||
|
self.prev_g5_q = search_string('Q', instruction)
|
||||||
|
control_2[0] = self.prev_g5_p + self.current_units[0]
|
||||||
|
control_2[1] = self.prev_g5_q + self.current_units[1]
|
||||||
|
|
||||||
|
length = bezier_length(self.current_units[0], self.current_units[1], *control_1, *control_2, fp[0], fp[1])
|
||||||
|
steps = np.ceil(length/self.curve_section)
|
||||||
|
|
||||||
|
newPoint = [0., 0., 0.]
|
||||||
|
for t in [i / steps for i in range(1, steps + 1)]:
|
||||||
|
newPoint[0] = (1 - t) ** 3 * self.current_units[0] + 3 * (1 - t) ** 2 * t * control_1[0] + 3 * (
|
||||||
|
1 - t) * t ** 2 * control_2[0] + t ** 3 * fp[0]
|
||||||
|
newPoint[1] = (1 - t) ** 3 * self.current_units[1] + 3 * (1 - t) ** 2 * t * control_1[1] + 3 * (
|
||||||
|
1 - t) * t ** 2 * control_2[1] + t ** 3 * fp[1]
|
||||||
|
self.set_target(newPoint[0], newPoint[1], fp[2])
|
||||||
|
|
||||||
|
if self.feedrate > 0:
|
||||||
|
self.feedrate_micros = self.calculate_feedrate_delay(self.feedrate)
|
||||||
|
else:
|
||||||
|
self.feedrate_micros = self.get_max_speed()
|
||||||
|
|
||||||
|
self.move(self.feedrate_micros)
|
||||||
|
|
||||||
|
case 5.1:
|
||||||
|
raise NotImplementedError("PAS DE SPLINE QUADRATIQUE J'AI LA FLEMME")
|
||||||
|
|
||||||
|
case 5.2, 5.3:
|
||||||
|
raise NotImplementedError("Experimental")
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
# Not canonical, but parabolas maybe
|
||||||
|
pass
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
# Not canonical, but ellipses
|
||||||
|
|
||||||
case 20:
|
case 20:
|
||||||
self.x_units = self.X_STEPS_PER_INCH
|
self.x_units = self.X_STEPS_PER_INCH
|
||||||
self.y_units = self.Y_STEPS_PER_INCH
|
self.y_units = self.Y_STEPS_PER_INCH
|
||||||
|
@ -343,14 +418,15 @@ class GCodeToMotors:
|
||||||
self.set_target(0., 0., 0.)
|
self.set_target(0., 0., 0.)
|
||||||
self.move(self.get_max_speed())
|
self.move(self.get_max_speed())
|
||||||
|
|
||||||
|
case _:
|
||||||
|
raise ValueError("No Associated GCode Implemented/Known")
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def execute(self, gcode):
|
def execute(self, gcode):
|
||||||
velocities = []
|
velocities = []
|
||||||
for instruction in gcode:
|
for instruction in gcode:
|
||||||
velocities.append(self.instruction_to_velocities(instruction))
|
velocities.append(self.instruction_converter(instruction))
|
||||||
return velocities
|
return velocities
|
||||||
|
|
||||||
|
|
||||||
|
|
1
main.py
1
main.py
|
@ -53,6 +53,7 @@ class SVGToGCodeConverter:
|
||||||
gcode_lines.append(self.point_to_gcode(x, y))
|
gcode_lines.append(self.point_to_gcode(x, y))
|
||||||
return gcode_lines
|
return gcode_lines
|
||||||
|
|
||||||
|
# Following two are not canonical, I don't know where I found those lol
|
||||||
def ellipse_to_gcode(self, start: complex, end: complex, center: complex, rx: float, ry: float, rotation: float, clockwise: bool) -> str:
|
def ellipse_to_gcode(self, start: complex, end: complex, center: complex, rx: float, ry: float, rotation: float, clockwise: bool) -> str:
|
||||||
if "G7" not in self.supported_g_functions:
|
if "G7" not in self.supported_g_functions:
|
||||||
raise NotImplementedError("Ellipse support requires G7 function.")
|
raise NotImplementedError("Ellipse support requires G7 function.")
|
||||||
|
|
Loading…
Reference in a new issue