shapely, simplify, accumulate error
This commit is contained in:
parent
ac976f10de
commit
66ab72311a
|
@ -1,6 +1,6 @@
|
||||||
from .device import Device
|
from .device import Device
|
||||||
from .drawing import Drawing
|
from .drawing import Drawing
|
||||||
from .paths import sort_paths, join_paths
|
from .paths import simplify_paths, sort_paths, join_paths
|
||||||
from .planner import Planner
|
from .planner import Planner
|
||||||
from .turtle import Turtle
|
from .turtle import Turtle
|
||||||
from .util import draw, reset
|
from .util import draw, reset
|
||||||
|
|
|
@ -19,7 +19,7 @@ PEN_DOWN_SPEED = 150
|
||||||
PEN_DOWN_DELAY = 100
|
PEN_DOWN_DELAY = 100
|
||||||
|
|
||||||
ACCELERATION = 8
|
ACCELERATION = 8
|
||||||
MAX_VELOCITY = 4
|
MAX_VELOCITY = 8
|
||||||
CORNER_FACTOR = 0.01
|
CORNER_FACTOR = 0.01
|
||||||
|
|
||||||
VID_PID = '04D8:FD92'
|
VID_PID = '04D8:FD92'
|
||||||
|
@ -46,6 +46,8 @@ class Device(object):
|
||||||
for k, v in kwargs.items():
|
for k, v in kwargs.items():
|
||||||
setattr(self, k, v)
|
setattr(self, k, v)
|
||||||
|
|
||||||
|
self.error = (0, 0) # accumulated step error
|
||||||
|
|
||||||
port = find_port()
|
port = find_port()
|
||||||
if port is None:
|
if port is None:
|
||||||
raise Exception('cannot find axidraw device')
|
raise Exception('cannot find axidraw device')
|
||||||
|
@ -102,17 +104,17 @@ class Device(object):
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
def run_plan(self, plan):
|
def run_plan(self, plan):
|
||||||
step_ms = 30
|
step_ms = 10
|
||||||
step_s = step_ms / 1000
|
step_s = step_ms / 1000
|
||||||
t = 0
|
t = 0
|
||||||
ex = 0
|
|
||||||
ey = 0
|
|
||||||
while t < plan.t:
|
while t < plan.t:
|
||||||
i1 = plan.instant(t)
|
i1 = plan.instant(t)
|
||||||
i2 = plan.instant(t + step_s)
|
i2 = plan.instant(t + step_s)
|
||||||
d = i2.p.sub(i1.p)
|
d = i2.p.sub(i1.p)
|
||||||
|
ex, ey = self.error
|
||||||
ex, sx = modf(d.x * self.steps_per_unit + ex)
|
ex, sx = modf(d.x * self.steps_per_unit + ex)
|
||||||
ey, sy = modf(d.y * self.steps_per_unit + ey)
|
ey, sy = modf(d.y * self.steps_per_unit + ey)
|
||||||
|
self.error = ex, ey
|
||||||
self.move(step_ms, int(sx), int(sy))
|
self.move(step_ms, int(sx), int(sy))
|
||||||
t += step_s
|
t += step_s
|
||||||
self.wait()
|
self.wait()
|
||||||
|
|
|
@ -2,7 +2,7 @@ from __future__ import division
|
||||||
|
|
||||||
from math import sin, cos, radians
|
from math import sin, cos, radians
|
||||||
|
|
||||||
from .paths import sort_paths, join_paths
|
from .paths import simplify_paths, sort_paths, join_paths
|
||||||
|
|
||||||
class Drawing(object):
|
class Drawing(object):
|
||||||
def __init__(self, paths=None):
|
def __init__(self, paths=None):
|
||||||
|
@ -33,6 +33,9 @@ class Drawing(object):
|
||||||
x1, y1, x2, y2 = self.bounds
|
x1, y1, x2, y2 = self.bounds
|
||||||
return y2 - y1
|
return y2 - y1
|
||||||
|
|
||||||
|
def simplify_paths(self, tolerance):
|
||||||
|
return Drawing(simplify_paths(self.paths, tolerance))
|
||||||
|
|
||||||
def sort_paths(self, reversable=True):
|
def sort_paths(self, reversable=True):
|
||||||
return Drawing(sort_paths(self.paths, reversable))
|
return Drawing(sort_paths(self.paths, reversable))
|
||||||
|
|
||||||
|
@ -42,9 +45,6 @@ class Drawing(object):
|
||||||
# def remove_duplicates(self):
|
# def remove_duplicates(self):
|
||||||
# return Drawing(util.remove_duplicates(self.paths))
|
# return Drawing(util.remove_duplicates(self.paths))
|
||||||
|
|
||||||
# def simplify_paths(self, tolerance=0.05):
|
|
||||||
# return Drawing(util.simplify_paths(self.paths, tolerance))
|
|
||||||
|
|
||||||
def transform(self, func):
|
def transform(self, func):
|
||||||
return Drawing([[func(x, y) for x, y in path] for path in self.paths])
|
return Drawing([[func(x, y) for x, y in path] for path in self.paths])
|
||||||
|
|
||||||
|
|
11
axi/paths.py
11
axi/paths.py
|
@ -1,7 +1,18 @@
|
||||||
from math import hypot
|
from math import hypot
|
||||||
|
from shapely.geometry import LineString
|
||||||
|
|
||||||
from .spatial import Index
|
from .spatial import Index
|
||||||
|
|
||||||
|
def simplify_path(points, tolerance):
|
||||||
|
if len(points) < 2:
|
||||||
|
return points
|
||||||
|
line = LineString(points)
|
||||||
|
line = line.simplify(tolerance)
|
||||||
|
return list(line.coords)
|
||||||
|
|
||||||
|
def simplify_paths(paths, tolerance):
|
||||||
|
return [simplify_path(x, tolerance) for x in paths]
|
||||||
|
|
||||||
def sort_paths(paths, reversable=True):
|
def sort_paths(paths, reversable=True):
|
||||||
first = paths[0]
|
first = paths[0]
|
||||||
paths.remove(first)
|
paths.remove(first)
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
import axi
|
||||||
|
import random
|
||||||
|
import time
|
||||||
|
|
||||||
|
def main():
|
||||||
|
d = axi.Device()
|
||||||
|
d.pen_up()
|
||||||
|
d.enable_motors()
|
||||||
|
time.sleep(0.2)
|
||||||
|
points = []
|
||||||
|
points.append((0, 0))
|
||||||
|
for i in range(10):
|
||||||
|
x = random.random() * 11
|
||||||
|
y = random.random() * 8.5
|
||||||
|
points.append((x, y))
|
||||||
|
points.append((0, 0))
|
||||||
|
d.run_path(points)
|
||||||
|
d.wait()
|
||||||
|
d.disable_motors()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
2
setup.py
2
setup.py
|
@ -7,7 +7,7 @@ setup(
|
||||||
author='Michael Fogleman',
|
author='Michael Fogleman',
|
||||||
author_email='michael.fogleman@gmail.com',
|
author_email='michael.fogleman@gmail.com',
|
||||||
packages=['axi'],
|
packages=['axi'],
|
||||||
install_requires=['pyserial'],
|
install_requires=['pyserial', 'shapely'],
|
||||||
license='MIT',
|
license='MIT',
|
||||||
classifiers=(
|
classifiers=(
|
||||||
'Development Status :: 3 - Alpha',
|
'Development Status :: 3 - Alpha',
|
||||||
|
|
Loading…
Reference in New Issue