Minor optimizations in gcode interpreter

master
Gina Häußge 2013-09-01 19:27:57 +02:00
parent 61481bf93f
commit e7eb9707fc
1 changed files with 18 additions and 109 deletions

View File

@ -1,13 +1,14 @@
from __future__ import absolute_import
__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
import sys
import math
import os
import base64
import zlib
import logging
from octoprint.settings import settings
preferences = {
"extruder_offset_x1": -22.0,
"extruder_offset_y1": 0.0,
@ -26,13 +27,6 @@ def getPreference(key, default=None):
class AnalysisAborted(Exception):
pass
def gcodePath(newType, pathType, layerThickness, startPoint):
return {'type': newType,
'pathType': pathType,
'layerThickness': layerThickness,
'points': [startPoint],
'extrusion': [0.0]}
class gcode(object):
def __init__(self):
self._logger = logging.getLogger(__name__)
@ -49,13 +43,8 @@ class gcode(object):
if os.path.isfile(filename):
self.filename = filename
self._fileSize = os.stat(filename).st_size
gcodeFile = open(filename, 'r')
self._load(gcodeFile)
gcodeFile.close()
def loadList(self, l):
self.filename = None
self._load(l)
with open(filename, "r") as f:
self._load(f)
def abort(self):
self._abort = True
@ -64,25 +53,8 @@ class gcode(object):
radius = self._filamentDiameter / 2
return (self.extrusionAmount * (math.pi * radius * radius)) / 1000
def calculateWeight(self):
#Calculates the weight of the filament in kg
volumeM3 = self.calculateVolumeCm3() /(1000*1000)
return volumeM3 * getPreference('filament_physical_density')
def calculateCost(self):
cost_kg = getPreference('filament_cost_kg')
cost_meter = getPreference('filament_cost_meter')
if cost_kg > 0.0 and cost_meter > 0.0:
return "%.2f / %.2f" % (self.calculateWeight() * cost_kg, self.extrusionAmount / 1000 * cost_meter)
elif cost_kg > 0.0:
return "%.2f" % (self.calculateWeight() * cost_kg)
elif cost_meter > 0.0:
return "%.2f" % (self.extrusionAmount / 1000 * cost_meter)
return None
def _load(self, gcodeFile):
filePos = 0
self.layerList = []
pos = [0.0, 0.0, 0.0]
posOffset = [0.0, 0.0, 0.0]
currentE = 0.0
@ -93,21 +65,21 @@ class gcode(object):
absoluteE = True
scale = 1.0
posAbs = True
feedRate = 3600.0
unknownGcodes = {}
unknownMcodes = {}
feedRateXY = settings().getFloat(["printerParameters", "movementSpeed", "x"])
for line in gcodeFile:
if self._abort:
raise AnalysisAborted()
if type(line) is tuple:
line = line[0]
filePos += 1
if self.progressCallback is not None and (filePos % 1000 == 0):
if isinstance(gcodeFile, (file)):
self.progressCallback(float(gcodeFile.tell()) / float(self._fileSize))
elif isinstance(gcodeFile, (list)):
self.progressCallback(float(filePos) / float(len(gcodeFile)))
try:
if self.progressCallback is not None and (filePos % 1000 == 0):
if isinstance(gcodeFile, (file)):
self.progressCallback(float(gcodeFile.tell()) / float(self._fileSize))
elif isinstance(gcodeFile, (list)):
self.progressCallback(float(filePos) / float(len(gcodeFile)))
except:
pass
if ';' in line:
comment = line[line.find(';')+1:].strip()
@ -157,11 +129,11 @@ class gcode(object):
if z is not None:
pos[2] += z * scale
if f is not None:
feedRate = f
feedRateXY = f
if x is not None or y is not None or z is not None:
diffX = oldPos[0] - pos[0]
diffY = oldPos[1] - pos[1]
totalMoveTimeMinute += math.sqrt(diffX * diffX + diffY * diffY) / feedRate
totalMoveTimeMinute += math.sqrt(diffX * diffX + diffY * diffY) / feedRateXY
moveType = 'move'
if e is not None:
if absoluteE:
@ -194,10 +166,7 @@ class gcode(object):
x = getCodeFloat(line, 'X')
y = getCodeFloat(line, 'Y')
z = getCodeFloat(line, 'Z')
if getPreference('machine_center_is_zero') == 'True':
center = [getPreference('machine_width') / 2, getPreference('machine_depth') / 2,0.0]
else:
center = [0.0,0.0,0.0]
center = [0.0,0.0,0.0]
if x is None and y is None and z is None:
pos = center
else:
@ -225,61 +194,13 @@ class gcode(object):
posOffset[1] = pos[1] - y
if z is not None:
posOffset[2] = pos[2] - z
else:
if G not in unknownGcodes:
self._logger.info("Unknown G code: %r" % G)
unknownGcodes[G] = True
else:
M = getCodeInt(line, 'M')
if M is not None:
if M == 0: #Message with possible wait (ignored)
pass
elif M == 1: #Message with possible wait (ignored)
pass
elif M == 80: #Enable power supply
pass
elif M == 81: #Suicide/disable power supply
pass
elif M == 82: #Absolute E
if M == 82: #Absolute E
absoluteE = True
elif M == 83: #Relative E
absoluteE = False
elif M == 84: #Disable step drivers
pass
elif M == 92: #Set steps per unit
pass
elif M == 101: #Enable extruder
pass
elif M == 103: #Disable extruder
pass
elif M == 104: #Set temperature, no wait
pass
elif M == 105: #Get temperature
pass
elif M == 106: #Enable fan
pass
elif M == 107: #Disable fan
pass
elif M == 108: #Extruder RPM (these should not be in the final GCode, but they are)
pass
elif M == 109: #Set temperature, wait
pass
elif M == 110: #Reset N counter
pass
elif M == 113: #Extruder PWM (these should not be in the final GCode, but they are)
pass
elif M == 117: #LCD message
pass
elif M == 140: #Set bed temperature
pass
elif M == 190: #Set bed temperature & wait
pass
elif M == 221: #Extrude amount multiplier
s = getCodeFloat(line, 'S')
else:
if M not in unknownMcodes:
self._logger.info("Unknown M code: %r" % M)
unknownMcodes[M] = True
if self.progressCallback is not None:
self.progressCallback(100.0)
self.extrusionAmount = maxExtrusion
@ -311,15 +232,3 @@ def getCodeFloat(line, code):
return float(line[n:m])
except:
return None
if __name__ == '__main__':
from time import time
t = time()
for filename in sys.argv[1:]:
g = gcode()
g.load(filename)
print g.totalMoveTimeMinute
print g.extrusionAmount
print g.calculateVolumeCm3()
print time() - t