outer arc linearization

This commit is contained in:
Peter Boin 2017-07-12 00:49:14 +10:00
parent 0d398d5330
commit 436ef53398
2 changed files with 50 additions and 10 deletions

View File

@ -1,4 +1,4 @@
from math import acos, atan2, pi, sqrt, ceil
from math import cos, acos, atan2, pi, sqrt, ceil
from .gcodes import GCodeLinearMove
from .gcodes import GCodeArcMove, GCodeArcMoveCW, GCodeArcMoveCCW
@ -14,8 +14,6 @@ from .utils import Vector3, Quaternion, plane_projection
# ==================== Arcs (G2,G3) --> Linear Motion (G1) ====================
class ArcLinearizeMethod(object):
pass
def __init__(self, max_error, plane_normal,
arc_p_start, arc_p_end, arc_p_center,
arc_radius, arc_angle, helical_start, helical_end):
@ -29,6 +27,9 @@ class ArcLinearizeMethod(object):
self.helical_start = helical_start
self.helical_end = helical_end
if self.max_error > self.arc_radius:
self.max_error = self.arc_radius
def get_max_wedge_angle(self):
"""Calculate angular coverage of a single line reaching maximum allowable error"""
raise NotImplementedError("not overridden")
@ -56,7 +57,7 @@ class ArcLinearizeInside(ArcLinearizeMethod):
start_radius = self.arc_p_start - self.arc_p_center
helical_delta = (self.helical_end - self.helical_start) / wedge_count
l_p_start = start_radius + self.arc_p_center
l_p_start = self.arc_p_start
l_start = l_p_start + self.helical_start
for i in range(wedge_count):
q_end = Quaternion.new_rotate_axis(
@ -70,9 +71,8 @@ class ArcLinearizeInside(ArcLinearizeMethod):
yield (l_start, l_end)
# start of next line is the end of this line
(l_p_start, l_start) = (l_p_end, l_end)
# start of next line is the end of this one
l_start = l_end
class ArcLinearizeOutside(ArcLinearizeMethod):
@ -83,6 +83,38 @@ class ArcLinearizeOutside(ArcLinearizeMethod):
# - perimeter milling action will remove less material
# - 1st and last lines are 1/2 length of the others
def get_max_wedge_angle(self):
return abs(2 * acos(self.arc_radius / (self.arc_radius + self.max_error)))
def iter_vertices(self):
# n wedges distributed like:
# - 1/2 wedge : first line
# - n-1 wedges : outer perimeter
# - last 1/2 wedge : last line
wedge_count = int(ceil(abs(self.arc_angle) / self.get_max_wedge_angle()))
wedge_angle = self.arc_angle / wedge_count
start_radius = self.arc_p_start - self.arc_p_center
# radius of outer circle (across which the linear lines will span)
error_radius = start_radius.normalized() * (self.arc_radius / cos(wedge_angle / 2))
l_p_start = start_radius + self.arc_p_center
l_start = l_p_start + self.helical_start
for i in range(wedge_count):
cur_angle = (wedge_angle * i) + (wedge_angle / 2)
q_end = Quaternion.new_rotate_axis(angle=cur_angle, axis=-self.plane_normal)
# Projected on selected plane
l_p_end = (q_end * error_radius) + self.arc_p_center
# Helical displacement
l_end = l_p_end + self.helical_start + ((self.helical_end - self.helical_start) * (cur_angle / self.arc_angle))
yield (l_start, l_end)
# start of next line is the end of this one
l_start = l_end
yield (l_start, self.arc_p_end + self.helical_end)
class ArcLinearizeMid(ArcLinearizeMethod):
"""Lines cross original arc from tangent of arc radius - precision/2, until it reaches arc radius + precision/2"""
@ -244,7 +276,7 @@ def linearize_arc(arc_gcode, start_pos, plane=None, method_class=None,
}
method = method_class(**method_class_params)
#import ipdb; ipdb.set_trace()
# Iterate & yield each linear line (start, end) vertices
if isinstance(dist_mode, GCodeAbsoluteDistanceMode):
# Absolute coordinates
for line_vertices in method.iter_vertices():

View File

@ -1,4 +1,11 @@
#!/usr/bin/env python
# Script to take (theoretically) any g-code file as input, and output a
# normalized version of it.
#
# Script outcome can have cursory verification with:
# https://nraynaud.github.io/webgcode/
import argparse
import re
from collections import defaultdict
@ -37,7 +44,8 @@ parser.add_argument(
parser.add_argument(
'--precision', '-p', dest='precision', type=float, default=DEFAULT_PRECISION,
help="maximum positional error when generating gcodes (eg: arcs to lines)",
help="maximum positional error when generating gcodes (eg: arcs to lines) "
"(default: %g)" % DEFAULT_PRECISION,
)
# Machine