diff --git a/axi/__init__.py b/axi/__init__.py index 9b0ac4d..1e8d3d7 100644 --- a/axi/__init__.py +++ b/axi/__init__.py @@ -1,6 +1,6 @@ from .device import Device 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 .turtle import Turtle from .util import draw, reset diff --git a/axi/device.py b/axi/device.py index 974512e..6c25c08 100644 --- a/axi/device.py +++ b/axi/device.py @@ -19,7 +19,7 @@ PEN_DOWN_SPEED = 150 PEN_DOWN_DELAY = 100 ACCELERATION = 8 -MAX_VELOCITY = 4 +MAX_VELOCITY = 8 CORNER_FACTOR = 0.01 VID_PID = '04D8:FD92' @@ -46,6 +46,8 @@ class Device(object): for k, v in kwargs.items(): setattr(self, k, v) + self.error = (0, 0) # accumulated step error + port = find_port() if port is None: raise Exception('cannot find axidraw device') @@ -102,17 +104,17 @@ class Device(object): time.sleep(0.1) def run_plan(self, plan): - step_ms = 30 + step_ms = 10 step_s = step_ms / 1000 t = 0 - ex = 0 - ey = 0 while t < plan.t: i1 = plan.instant(t) i2 = plan.instant(t + step_s) d = i2.p.sub(i1.p) + ex, ey = self.error ex, sx = modf(d.x * self.steps_per_unit + ex) ey, sy = modf(d.y * self.steps_per_unit + ey) + self.error = ex, ey self.move(step_ms, int(sx), int(sy)) t += step_s self.wait() diff --git a/axi/drawing.py b/axi/drawing.py index 504a3b8..c3e807a 100644 --- a/axi/drawing.py +++ b/axi/drawing.py @@ -2,7 +2,7 @@ from __future__ import division 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): def __init__(self, paths=None): @@ -33,6 +33,9 @@ class Drawing(object): x1, y1, x2, y2 = self.bounds return y2 - y1 + def simplify_paths(self, tolerance): + return Drawing(simplify_paths(self.paths, tolerance)) + def sort_paths(self, reversable=True): return Drawing(sort_paths(self.paths, reversable)) @@ -42,9 +45,6 @@ class Drawing(object): # def remove_duplicates(self): # 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): return Drawing([[func(x, y) for x, y in path] for path in self.paths]) diff --git a/axi/paths.py b/axi/paths.py index 888b6da..72c87c6 100644 --- a/axi/paths.py +++ b/axi/paths.py @@ -1,7 +1,18 @@ from math import hypot +from shapely.geometry import LineString 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): first = paths[0] paths.remove(first) diff --git a/examples/motor_test.py b/examples/motor_test.py new file mode 100644 index 0000000..b593a3c --- /dev/null +++ b/examples/motor_test.py @@ -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() diff --git a/setup.py b/setup.py index 4ffd862..a0f6596 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ setup( author='Michael Fogleman', author_email='michael.fogleman@gmail.com', packages=['axi'], - install_requires=['pyserial'], + install_requires=['pyserial', 'shapely'], license='MIT', classifiers=( 'Development Status :: 3 - Alpha',