Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor extruder steppers and extruder_stepper #5143

Merged
merged 4 commits into from
Jan 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/Config_Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -1835,8 +1835,9 @@ more information.
```
[extruder_stepper my_extra_stepper]
#extruder: extruder
# The extruder this stepper is synchronized to. The default is
# "extruder".
# The extruder this stepper is synchronized to. If this is set to an
# empty string then the stepper will not be synchronized to an
# extruder. The default is "extruder".
#step_pin:
#dir_pin:
#enable_pin:
Expand Down
17 changes: 7 additions & 10 deletions docs/G-Codes.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,13 @@ The following standard commands are supported:
result in excessive pressure between extruder and hot end. Do proper
calibration steps with filament before use. If 'DISTANCE' value is
not included command will return current step distance.
- `SYNC_STEPPER_TO_EXTRUDER STEPPER=<name> [EXTRUDER=<name>]`: This
command will cause the given extruder STEPPER (as specified in an
[extruder](Config_Reference#extruder) or
[extruder stepper](Config_Reference#extruder_stepper) config
section) to become synchronized to the given EXTRUDER. If EXTRUDER
is an empty string then the stepper will not be synchronized to an
extruder.
- `SET_STEPPER_ENABLE STEPPER=<config_name> ENABLE=[0|1]`: Enable or
disable only the given stepper. This is a diagnostic and debugging
tool and must be used with care. Disabling an axis motor does not
Expand Down Expand Up @@ -344,16 +351,6 @@ enabled:
future G-Code movement commands may run in parallel with the stepper
movement.

### Extruder stepper Commands

The following command is available when an
[extruder_stepper config section](Config_Reference.md#extruder_stepper)
is enabled:
- `SYNC_STEPPER_TO_EXTRUDER STEPPER=<extruder_stepper config_name>
[EXTRUDER=<extruder config_name>]`: This command will cause the given
STEPPER to become synchronized to the given EXTRUDER, overriding
the extruder defined in the "extruder_stepper" config section.

### Probe

The following commands are available when a
Expand Down
4 changes: 2 additions & 2 deletions klippy/chelper/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@

defs_kin_extruder = """
struct stepper_kinematics *extruder_stepper_alloc(void);
void extruder_set_smooth_time(struct stepper_kinematics *sk
, double smooth_time);
void extruder_set_pressure_advance(struct stepper_kinematics *sk
, double pressure_advance, double smooth_time);
"""

defs_kin_shaper = """
Expand Down
28 changes: 17 additions & 11 deletions klippy/chelper/kin_extruder.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,17 @@ extruder_integrate_time(double base, double start_v, double half_accel

// Calculate the definitive integral of extruder for a given move
static double
pa_move_integrate(struct move *m, double base, double start, double end,
double time_offset)
pa_move_integrate(struct move *m, double pressure_advance
, double base, double start, double end, double time_offset)
{
if (start < 0.)
start = 0.;
if (end > m->move_t)
end = m->move_t;
// Calculate base position and velocity with pressure advance
double pressure_advance = m->axes_r.y;
int can_pressure_advance = m->axes_r.y != 0.;
if (!can_pressure_advance)
pressure_advance = 0.;
base += pressure_advance * m->start_v;
double start_v = m->start_v + pressure_advance * 2. * m->half_accel;
// Calculate definitive integral
Expand All @@ -72,34 +74,36 @@ pa_move_integrate(struct move *m, double base, double start, double end,

// Calculate the definitive integral of the extruder over a range of moves
static double
pa_range_integrate(struct move *m, double move_time, double hst)
pa_range_integrate(struct move *m, double move_time
, double pressure_advance, double hst)
{
// Calculate integral for the current move
double res = 0., start = move_time - hst, end = move_time + hst;
double start_base = m->start_pos.x;
res += pa_move_integrate(m, 0., start, move_time, start);
res -= pa_move_integrate(m, 0., move_time, end, end);
res += pa_move_integrate(m, pressure_advance, 0., start, move_time, start);
res -= pa_move_integrate(m, pressure_advance, 0., move_time, end, end);
// Integrate over previous moves
struct move *prev = m;
while (unlikely(start < 0.)) {
prev = list_prev_entry(prev, node);
start += prev->move_t;
double base = prev->start_pos.x - start_base;
res += pa_move_integrate(prev, base, start, prev->move_t, start);
res += pa_move_integrate(prev, pressure_advance, base, start
, prev->move_t, start);
}
// Integrate over future moves
while (unlikely(end > m->move_t)) {
end -= m->move_t;
m = list_next_entry(m, node);
double base = m->start_pos.x - start_base;
res -= pa_move_integrate(m, base, 0., end, end);
res -= pa_move_integrate(m, pressure_advance, base, 0., end, end);
}
return res;
}

struct extruder_stepper {
struct stepper_kinematics sk;
double half_smooth_time, inv_half_smooth_time2;
double pressure_advance, half_smooth_time, inv_half_smooth_time2;
};

static double
Expand All @@ -112,12 +116,13 @@ extruder_calc_position(struct stepper_kinematics *sk, struct move *m
// Pressure advance not enabled
return m->start_pos.x + move_get_distance(m, move_time);
// Apply pressure advance and average over smooth_time
double area = pa_range_integrate(m, move_time, hst);
double area = pa_range_integrate(m, move_time, es->pressure_advance, hst);
return m->start_pos.x + area * es->inv_half_smooth_time2;
}

void __visible
extruder_set_smooth_time(struct stepper_kinematics *sk, double smooth_time)
extruder_set_pressure_advance(struct stepper_kinematics *sk
, double pressure_advance, double smooth_time)
{
struct extruder_stepper *es = container_of(sk, struct extruder_stepper, sk);
double hst = smooth_time * .5;
Expand All @@ -126,6 +131,7 @@ extruder_set_smooth_time(struct stepper_kinematics *sk, double smooth_time)
if (! hst)
return;
es->inv_half_smooth_time2 = 1. / (hst * hst);
es->pressure_advance = pressure_advance;
}

struct stepper_kinematics * __visible
Expand Down
29 changes: 5 additions & 24 deletions klippy/extras/extruder_stepper.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,17 @@
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import logging
import stepper
from kinematics import extruder

class ExtruderStepper:
class PrinterExtruderStepper:
def __init__(self, config):
self.printer = config.get_printer()
stepper_name = config.get_name().split()[1]
self.extruder_stepper = extruder.ExtruderStepper(config)
self.extruder_name = config.get('extruder', 'extruder')
self.stepper = stepper.PrinterStepper(config)
self.stepper.setup_itersolve('extruder_stepper_alloc')
self.printer.register_event_handler("klippy:connect",
self.handle_connect)
gcode = self.printer.lookup_object('gcode')
gcode.register_mux_command("SYNC_STEPPER_TO_EXTRUDER", "STEPPER",
stepper_name,
self.cmd_SYNC_STEPPER_TO_EXTRUDER,
desc=self.cmd_SYNC_STEPPER_TO_EXTRUDER_help)
def handle_connect(self):
extruder = self.printer.lookup_object(self.extruder_name)
extruder.sync_stepper(self.stepper)
toolhead = self.printer.lookup_object('toolhead')
toolhead.register_step_generator(self.stepper.generate_steps)
cmd_SYNC_STEPPER_TO_EXTRUDER_help = "Set extruder stepper"
def cmd_SYNC_STEPPER_TO_EXTRUDER(self, gcmd):
ename = gcmd.get('EXTRUDER')
extruder = self.printer.lookup_object(ename, None)
if extruder is None:
raise gcmd.error("'%s' is not a valid extruder." % (ename,))
extruder.sync_stepper(self.stepper)
self.extruder_name = ename
gcmd.respond_info("Extruder stepper now syncing with '%s'" % (ename,))
self.extruder_stepper.sync_to_extruder(self.extruder_name)

def load_config_prefix(config):
return ExtruderStepper(config)
return PrinterExtruderStepper(config)
Loading