Skip to content

Instantly share code, notes, and snippets.

@jkramarz
Created October 14, 2017 05:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jkramarz/f9dae208b3a11e8a74622078c3938ba6 to your computer and use it in GitHub Desktop.
Save jkramarz/f9dae208b3a11e8a74622078c3938ba6 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python2
import re
import turtle
import sys
import math
def to_mm(distance):
return distance * 0.0254;
def to_mils(distance):
return distance * 39.37008;
rapid = False
def parse_move(move_string):
direction = {
"T": "LEFT",
"B": "RIGHT",
"L": "UP",
"R": "DOWN",
"M": tuple(current_angle)
}[move_string[0]]
distance_string = move_string[1:]
scanner=re.Scanner([
(r"z", 255),
(r"\|[a-y]", lambda scanner, token: ord(token[1]) + 25 - 96),
(r"[a-y]", lambda scanner, token: ord(token[0]) - 96),
(r"[0-9]+", lambda scanner, token: int(token)),
])
distance_tokens, distance_remainder = scanner.scan(distance_string)
distance = sum(distance_tokens)
if rapid:
return ("RAPID_MOVE", (direction, distance))
else:
return ("MOVE", (direction, distance))
current_angle = ["DOWN", "RIGHT"]
def parse_angle(angle_string):
global current_angle
if angle_string == "T":
current_angle[1] = "LEFT"
elif angle_string == "B":
current_angle[1] = "RIGHT"
elif angle_string == "L":
current_angle[0] = "UP"
elif angle_string == "R":
current_angle[0] = "DOWN"
def parse_speed(speed_string):
return "DUNNO"
def parse_rapid_start():
global rapid
rapid = True;
return ("RAPID_MOVE_START",)
def parse_rapid_end():
global rapid
rapid = True;
return ("RAPID_MOVE_END",)
def tokenizer(command_stream):
scanner=re.Scanner ([
(r"I", lambda scanner, token: ("INITIALIZE",)),
(r"CV[0-9]+000000000", lambda scanner, token: ("VECTOR_SPEED", parse_speed(token))),
(r"V[0-9]+G[0-9]+", lambda scanner, token: ("RASTER_SPEED", token)),
(r"D", lambda scanner, token: ("LASER", True)),
(r"U", lambda scanner, token: ("LASER", False)),
(r"IPP", lambda scanner, token: ("HOME",)),
(r"IS2S", lambda scanner, token: ("UNLOCK_RAIL",)),
(r"(M|B|T|L|R)((z*((\|?[a-y]+)|([0-9]{3})))|(z+))", lambda scanner, token: parse_move(token)),
(r"TN", lambda scanner, token: ("WTF_MOVE_START", token)),
(r"BN", lambda scanner, token: parse_rapid_start()),
(r"SE", lambda scanner, token: parse_rapid_end()),
(r"(B|T|L|R)", lambda scanner, token: (parse_angle(token))),
(r"NRBS1E", lambda scanner, token: ("JOB_START",)),
(r"NSE", lambda scanner, token: ("JOB_END",)),
(r"F", lambda scanner, token: ("FINALIZE",)),
])
return scanner.scan(command_stream)
def tokens_to_gcode(tokens):
yield "G90"
absolute_horizontal = 0;
absolute_vertical = 0;
for token in results:
if token[0] in ("MOVE", "RAPID_MOVE"):
direction, distance = token[1]
if type(direction) is not tuple:
if direction == "UP":
absolute_vertical += distance
elif direction == "DOWN":
absolute_vertical -= distance
elif direction == "RIGHT":
absolute_horizontal += distance
elif direction == "LEFT":
absolute_horizontal -= distance
else:
if direction[0] == "UP":
absolute_vertical += distance
else:
absolute_vertical -= distance
if direction[1] == "RIGHT":
absolute_horizontal += distance
else:
absolute_horizontal -= distance
if token[0] == "MOVE":
yield "G1 X%3.2f Y%3.2f" % ( to_mm(absolute_horizontal), to_mm(absolute_vertical) )
else:
yield "G0 X%3.2f Y%3.2f" % ( to_mm(absolute_horizontal), to_mm(absolute_vertical) )
elif token[0] == "LASER":
if token[1]:
yield "G1 S1"
else:
yield "G1 S0"
yield "M2"
yield "M5"
def tokens_to_turtle(tokens):
turtle.mode("standard")
turtle.setup(600, 400)
wn = turtle.Screen()
wn.setworldcoordinates(0,-200,300,0)
alex = turtle.Turtle()
alex.penup()
# alex.ht()
alex.speed(0)
alex.tracer(100, 100)
alex.setposition(0, 0)
for token in results:
if token[0] in ("MOVE", "RAPID_MOVE"):
direction, distance = token[1]
if type(direction) is not tuple:
alex.setheading({
"UP": 90,
"RIGHT": 0,
"DOWN": 270,
"LEFT": 180
}[direction])
alex.forward(to_mm(distance))
else:
angle = {
("UP", "RIGHT"): 45,
("DOWN", "RIGHT"): 270+45,
("DOWN", "LEFT"): 180+45,
("UP", "LEFT"): 90+45,
}[direction]
alex.setheading(angle)
move_by = to_mm(distance * 1.414213562)
alex.forward(move_by)
elif token[0] == "LASER":
if token[1]:
alex.pendown()
else:
alex.penup()
wn.exitonclick()
if __name__ == "__main__":
with open(sys.argv[1], 'rb') as f:
command_stream = re.sub(r"\W", "", f.read())
results, remainder = tokenizer(
command_stream
)
tokens_to_turtle(results)
for command in tokens_to_gcode(results):
print command
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment