extruder: Create a new class and python file to track the printer extruder

Create a new python file (extruder.py) to control the extruder heater
and stepper motors.  This separates the extruder control logic from
the cartesian robot code - making it easier to customize both the
kinematic control of the robot as well as the extruder.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor
2016-07-10 12:23:35 -04:00
parent 4a527a46ce
commit af99ab1645
8 changed files with 88 additions and 27 deletions

View File

@@ -6,14 +6,14 @@
import logging
import stepper, homing
StepList = (0, 1, 2, 3)
StepList = (0, 1, 2)
class CartKinematics:
def __init__(self, printer, config):
steppers = ['stepper_x', 'stepper_y', 'stepper_z', 'stepper_e']
steppers = ['stepper_x', 'stepper_y', 'stepper_z']
self.steppers = [stepper.PrinterStepper(printer, config.getsection(n))
for n in steppers]
self.stepper_pos = [0, 0, 0, 0]
self.stepper_pos = [0, 0, 0]
def build_config(self):
for stepper in self.steppers:
stepper.build_config()
@@ -31,9 +31,6 @@ class CartKinematics:
accel_factor = min([self.steppers[i].max_accel / abs(axes_d[i])
for i in StepList if axes_d[i]])
return velocity_factor * move_d, accel_factor * move_d
def get_max_e_speed(self):
s = self.steppers[3]
return s.max_velocity, s.max_accel
def home(self, toolhead, axis):
# Each axis is homed independently and in order
homing_state = homing.Homing(toolhead, self.steppers) # XXX

62
klippy/extruder.py Normal file
View File

@@ -0,0 +1,62 @@
# Code for handling printer nozzle extruders
#
# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import logging
import stepper, heater
class PrinterExtruder:
def __init__(self, printer, config):
cfg = config.getsection('extruder')
self.heater = heater.PrinterHeater(printer, cfg)
self.stepper = stepper.PrinterStepper(printer, cfg)
self.stepper_pos = 0
def build_config(self):
self.heater.build_config()
self.stepper.build_config()
def get_max_speed(self):
return self.stepper.max_velocity, self.stepper.max_accel
def motor_off(self, move_time):
self.stepper.motor_enable(move_time, 0)
def move(self, move_time, move):
inv_accel = 1. / move.accel
new_step_pos = int(move.pos[3]*self.stepper.inv_step_dist + 0.5)
steps = new_step_pos - self.stepper_pos
if not steps:
return
self.stepper_pos = new_step_pos
sdir = 0
if steps < 0:
sdir = 1
steps = -steps
clock_offset, clock_freq, so = self.stepper.prep_move(sdir, move_time)
step_dist = move.move_d / steps
step_offset = 0.5
# Acceleration steps
#t = sqrt(2*pos/accel + (start_v/accel)**2) - start_v/accel
accel_clock_offset = move.start_v * inv_accel * clock_freq
accel_sqrt_offset = accel_clock_offset**2
accel_multiplier = 2.0 * step_dist * inv_accel * clock_freq**2
accel_steps = move.accel_r * steps
step_offset = so.step_sqrt(
accel_steps, step_offset, clock_offset - accel_clock_offset
, accel_sqrt_offset, accel_multiplier)
clock_offset += move.accel_t * clock_freq
# Cruising steps
#t = pos/cruise_v
cruise_multiplier = step_dist * clock_freq / move.cruise_v
cruise_steps = move.cruise_r * steps
step_offset = so.step_factor(
cruise_steps, step_offset, clock_offset, cruise_multiplier)
clock_offset += move.cruise_t * clock_freq
# Deceleration steps
#t = cruise_v/accel - sqrt((cruise_v/accel)**2 - 2*pos/accel)
decel_clock_offset = move.cruise_v * inv_accel * clock_freq
decel_sqrt_offset = decel_clock_offset**2
decel_steps = move.decel_r * steps
so.step_sqrt(
decel_steps, step_offset, clock_offset + decel_clock_offset
, decel_sqrt_offset, -accel_multiplier)

View File

@@ -35,7 +35,10 @@ class GCodeParser:
self.axis2pos = {'X': 0, 'Y': 1, 'Z': 2, 'E': 3}
def build_config(self):
self.toolhead = self.printer.objects['toolhead']
self.heater_nozzle = self.printer.objects.get('heater_nozzle')
self.heater_nozzle = None
extruder = self.printer.objects.get('extruder')
if extruder:
self.heater_nozzle = extruder.heater
self.heater_bed = self.printer.objects.get('heater_bed')
self.fan = self.printer.objects.get('fan')
self.build_handlers()

View File

@@ -5,7 +5,7 @@
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import sys, optparse, ConfigParser, logging, time, threading
import gcode, toolhead, util, mcu, fan, heater, reactor
import gcode, toolhead, util, mcu, fan, heater, extruder, reactor
class ConfigWrapper:
def __init__(self, printer, section):
@@ -52,9 +52,9 @@ class Printer:
if self.fileconfig.has_section('fan'):
self.objects['fan'] = fan.PrinterFan(
self, ConfigWrapper(self, 'fan'))
if self.fileconfig.has_section('heater_nozzle'):
self.objects['heater_nozzle'] = heater.PrinterHeater(
self, ConfigWrapper(self, 'heater_nozzle'))
if self.fileconfig.has_section('extruder'):
self.objects['extruder'] = extruder.PrinterExtruder(
self, ConfigWrapper(self, 'extruder'))
if self.fileconfig.has_section('heater_bed'):
self.objects['heater_bed'] = heater.PrinterHeater(
self, ConfigWrapper(self, 'heater_bed'))

View File

@@ -61,6 +61,8 @@ class Move:
# Generate step times for the move
next_move_time = self.toolhead.get_next_move_time()
self.toolhead.kin.move(next_move_time, self)
if self.axes_d[3]:
self.toolhead.extruder.move(next_move_time, self)
self.toolhead.update_move_time(accel_t + cruise_t + decel_t)
# Class to track a list of pending move requests and to facilitate
@@ -113,6 +115,7 @@ class ToolHead:
def __init__(self, printer, config):
self.printer = printer
self.reactor = printer.reactor
self.extruder = printer.objects.get('extruder')
self.kin = cartesian.CartKinematics(printer, config)
self.max_xy_speed, self.max_xy_accel = self.kin.get_max_xy_speed()
self.junction_deviation = config.getfloat('junction_deviation', 0.02)
@@ -208,7 +211,7 @@ class ToolHead:
move.process(0., 0.)
def _move_only_e(self, newpos, axes_d, speed):
self.move_queue.flush()
kin_speed, kin_accel = self.kin.get_max_e_speed()
kin_speed, kin_accel = self.extruder.get_max_speed()
speed = min(speed, self.max_xy_speed, kin_speed)
accel = min(self.max_xy_accel, kin_accel)
move = Move(self, newpos, abs(axes_d[3]), axes_d, speed, accel)
@@ -238,5 +241,6 @@ class ToolHead:
self.dwell(STALL_TIME)
last_move_time = self.get_last_move_time()
self.kin.motor_off(last_move_time)
self.extruder.motor_off(last_move_time)
self.dwell(STALL_TIME)
logging.debug('; Max time of %f' % (last_move_time,))