Commit 208be01c authored by Guillaume Seguin's avatar Guillaume Seguin

Initial untested implementation of gcoder-based printing.

parent b6159d8f
......@@ -22,6 +22,7 @@ import time, getopt, sys
import platform, os
from collections import deque
from GCodeAnalyzer import GCodeAnalyzer
from printrun import gcoder
def control_ttyhup(port, disable_hup):
"""Controls the HUPCL"""
......@@ -48,7 +49,7 @@ class printcore():
self.clear = 0 #clear to send, enabled after responses
self.online = False #The printer has responded to the initial command and is active
self.printing = False #is a print currently running, true if printing, false if paused
self.mainqueue = []
self.mainqueue = None
self.priqueue = []
self.queueindex = 0
self.lineno = 0
......@@ -204,8 +205,8 @@ class printcore():
def _checksum(self, command):
return reduce(lambda x, y:x^y, map(ord, command))
def startprint(self, data, startindex = 0):
"""Start a print, data is an array of gcode commands.
def startprint(self, gcode, startindex = 0):
"""Start a print, gcode is an array of gcode commands.
returns True on success, False if already printing.
The print queue will be replaced with the contents of the data array, the next line will be set to 0 and the firmware notified.
Printing will then start in a parallel thread.
......@@ -213,12 +214,12 @@ class printcore():
if self.printing or not self.online or not self.printer:
return False
self.printing = True
self.mainqueue = [] + data
self.mainqueue = gcode
self.lineno = 0
self.queueindex = startindex
self.resendfrom = -1
self._send("M110", -1, True)
if len(data) == 0:
if not gcode.lines:
return True
self.clear = False
self.print_thread = Thread(target = self._print)
......@@ -265,8 +266,6 @@ class printcore():
self.pauseF = self.analyzer.f;
self.pauseRelative = self.analyzer.relative;
def resume(self):
"""Resumes a paused print.
"""
......@@ -380,13 +379,13 @@ class printcore():
if self.priqueue:
self._send(self.priqueue.pop(0))
return
if self.printing and self.queueindex < len(self.mainqueue):
tline = self.mainqueue[self.queueindex]
if self.printing and self.queueindex < len(self.mainqueue.idxs):
(layer, line) = self.mainqueue.idxs[self.queueindex]
tline = self.mainqueue.all_layers[layer].lines[line].raw
#check for host command
if tline.lstrip().startswith(";@"):
#it is a host command: pop it from the list
self.mainqueue.pop(self.queueindex)
self.processHostCommand(tline)
self.queueindex += 1
return
tline = tline.split(";")[0]
......@@ -455,7 +454,8 @@ if __name__ == '__main__':
p = printcore(port, baud)
p.loud = loud
time.sleep(2)
gcode = [i.replace("\n", "") for i in open(filename)]
gcode = [i.strip() for i in open(filename)]
gcode = gcoder.GCode(gcode)
p.startprint(gcode)
try:
......
......@@ -130,6 +130,12 @@ class GCode(object):
layers = None
all_layers = None
idxs = None
append_layer = None
append_layer_id = None
imperial = False
relative = False
relative_e = False
def __init__(self,data):
self.lines = [Line(l2) for l2 in
......@@ -138,11 +144,26 @@ class GCode(object):
self._preprocess()
self._create_layers()
def _preprocess(self):
def __len__(self):
return len(self.idxs)
def append(self, command):
command = command.strip()
if not command:
return
gline = Line(command)
self.lines.append(gline)
self._preprocess([gline])
self.append_layer.lines.append(gline)
self.idxs.append((self.append_layer_id, len(self.append_layer.lines)))
def _preprocess(self, lines = None):
"""Checks for G20, G21, G90 and G91, sets imperial and relative flags"""
imperial = False
relative = False
relative_e = False
if not lines:
lines = self.lines
imperial = self.imperial
relative = self.relative
relative_e = self.relative_e
for line in self.lines:
if line.is_move:
line.relative = relative
......@@ -163,6 +184,9 @@ class GCode(object):
relative_e = True
if line.command[0] == "G":
line.parse_coordinates(imperial)
self.imperial = imperial
self.relative = relative
self.relative_e = relative_e
# FIXME : looks like this needs to be tested with list Z on move
def _create_layers(self):
......@@ -218,6 +242,9 @@ class GCode(object):
else:
del layers[idx]
self.append_layer_id = len(all_layers)
self.append_layer = Layer([])
all_layers.append(self.append_layer)
self.all_layers = all_layers
self.layers = layers
self.idxs = idxs
......
......@@ -629,7 +629,7 @@ class pronsole(cmd.Cmd):
self.log(_("Uploading %s") % self.filename)
self.p.send_now("M28 " + targetname)
self.log(_("Press Ctrl-C to interrupt upload."))
self.p.startprint(self.f)
self.p.startprint(self.fgcode)
try:
sys.stdout.write(_("Progress: ") + "00.0%")
sys.stdout.flush()
......@@ -651,7 +651,7 @@ class pronsole(cmd.Cmd):
self.p.send_now("M29 "+targetname)
time.sleep(0.2)
self.p.clear = 1
self.p.startprint([])
self.p.startprint(None)
self.log(_("A partial file named %s may have been written to the sd card.") % targetname)
def complete_upload(self, text, line, begidx, endidx):
......@@ -668,13 +668,13 @@ class pronsole(cmd.Cmd):
self.log("Uploads a gcode file to the sd card")
def help_print(self):
if not self.f:
if not self.fgcode:
self.log(_("Send a loaded gcode file to the printer. Load a file with the load command first."))
else:
self.log(_("Send a loaded gcode file to the printer. You have %s loaded right now.") % self.filename)
def do_print(self, l):
if not self.f:
if not self.fgcode:
self.log(_("No file loaded. Please use load first."))
return
if not self.p.online:
......@@ -682,7 +682,7 @@ class pronsole(cmd.Cmd):
return
self.log(_("Printing %s") % self.filename)
self.log(_("You can monitor the print with the monitor command."))
self.p.startprint(self.f)
self.p.startprint(self.fgcode)
def do_pause(self, l):
if self.sdprinting:
......
......@@ -587,7 +587,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
obj = e.GetEventObject()
popupmenu = wx.Menu()
item = popupmenu.Append(-1, _("SD Upload"))
if not self.f or not len(self.f):
if not self.f:
item.Enable(False)
self.Bind(wx.EVT_MENU, self.upload, id = item.GetId())
item = popupmenu.Append(-1, _("SD Print"))
......@@ -605,7 +605,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
wx.CallAfter(self.btemp.SetInsertionPoint, 0)
def showwin(self, event):
if self.f is not None:
if self.f:
self.gwindow.Show(True)
self.gwindow.SetToolTip(wx.ToolTip("Mousewheel zooms the display\nShift / Mousewheel scrolls layers"))
self.gwindow.Raise()
......@@ -1236,13 +1236,12 @@ class PronterWindow(MainWindow, pronsole.pronsole):
fn = self.filename
try:
self.filename = self.filename.replace(".stl", "_export.gcode").replace(".STL", "_export.gcode").replace(".obj", "_export.gcode").replace(".OBJ", "_export.gcode")
of = open(self.filename)
self.f = [i.replace("\n", "").replace("\r", "") for i in of]
of.close()
self.f = [line.strip() for line in open(self.filename)]
self.fgcode = gcoder.GCode(self.f)
if self.p.online:
wx.CallAfter(self.printbtn.Enable)
wx.CallAfter(self.status.SetStatusText, _("Loaded ")+self.filename+_(", %d lines") % (len(self.f),))
wx.CallAfter(self.status.SetStatusText, _("Loaded %s, %d lines") % (self.filename, len(self.f),))
wx.CallAfter(self.pausebtn.Disable)
wx.CallAfter(self.printbtn.SetLabel, _("Print"))
......@@ -1299,9 +1298,8 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.skein(name)
else:
self.filename = name
of = open(self.filename)
self.f = [i.replace("\n", "").replace("\r", "") for i in of]
of.close()
self.f = [line.strip() for line in open(self.filename)]
self.fgcode = gcoder.GCode(self.f)
self.status.SetStatusText(_("Loaded %s, %d lines") % (name, len(self.f)))
wx.CallAfter(self.printbtn.SetLabel, _("Print"))
wx.CallAfter(self.pausebtn.SetLabel, _("Pause"))
......@@ -1337,14 +1335,14 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.p.send_now("M24")
return
if self.f is None or not len(self.f):
if not self.f:
wx.CallAfter(self.status.SetStatusText, _("No file loaded. Please use load first."))
return
if not self.p.online:
wx.CallAfter(self.status.SetStatusText, _("Not connected to printer."))
return
self.on_startprint()
self.p.startprint(self.f)
self.p.startprint(self.fgcode)
def on_startprint(self):
wx.CallAfter(self.pausebtn.SetLabel, _("Pause"))
......@@ -1361,14 +1359,14 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def uploadtrigger(self, l):
if "Writing to file" in l:
self.uploading = True
self.p.startprint(self.f)
self.p.startprint(self.fgcode)
self.p.endcb = self.endupload
self.recvlisteners.remove(self.uploadtrigger)
elif "open failed, File" in l:
self.recvlisteners.remove(self.uploadtrigger)
def upload(self, event):
if not self.f or not len(self.f):
if not self.f:
return
if not self.p.online:
return
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment