Bugfix: pressure regulation accumulated too much retraction and didn't discharge at the end of print. Includes regression test. #2470
This commit is contained in:
parent
9fd0637990
commit
0f7933c4f9
3 changed files with 38 additions and 27 deletions
|
@ -24,7 +24,7 @@ sub BUILD {
|
|||
|
||||
sub process {
|
||||
my $self = shift;
|
||||
my ($gcode) = @_;
|
||||
my ($gcode, $flush) = @_;
|
||||
|
||||
my $new_gcode = "";
|
||||
|
||||
|
@ -51,7 +51,7 @@ sub process {
|
|||
if (abs($new_advance - $self->_advance) > 1E-5) {
|
||||
my $new_E = ($self->config->use_relative_e_distances ? 0 : $reader->E) + ($new_advance - $self->_advance);
|
||||
$new_gcode .= sprintf "G1 %s%.5f F%.3f ; pressure advance\n",
|
||||
$self->_extrusion_axis, $new_E, $self->unretract_speed;
|
||||
$self->_extrusion_axis, $new_E, $self->_unretract_speed;
|
||||
$new_gcode .= sprintf "G92 %s%.5f ; restore E\n", $self->_extrusion_axis, $reader->E
|
||||
if !$self->config->use_relative_e_distances;
|
||||
$self->_advance($new_advance);
|
||||
|
@ -61,20 +61,33 @@ sub process {
|
|||
}
|
||||
} elsif (($info->{retracting} || $cmd eq 'G10') && $self->_advance != 0) {
|
||||
# We need to bring pressure to zero when retracting.
|
||||
my $new_E = ($self->config->use_relative_e_distances ? 0 : $reader->E) - $self->_advance;
|
||||
$new_gcode .= sprintf "G1 %s%.5f F%.3f ; pressure discharge\n",
|
||||
$self->_extrusion_axis, $new_E, $args->{F} // $self->unretract_speed;
|
||||
$new_gcode .= sprintf "G92 %s%.5f ; restore E\n", $self->_extrusion_axis, $reader->E
|
||||
if !$self->config->use_relative_e_distances;
|
||||
$new_gcode .= $self->_discharge($args->{F});
|
||||
}
|
||||
|
||||
$new_gcode .= "$info->{raw}\n";
|
||||
});
|
||||
|
||||
if ($flush) {
|
||||
$new_gcode .= $self->_discharge;
|
||||
}
|
||||
|
||||
return $new_gcode;
|
||||
}
|
||||
|
||||
sub unretract_speed {
|
||||
sub _discharge {
|
||||
my ($self, $F) = @_;
|
||||
|
||||
my $new_E = ($self->config->use_relative_e_distances ? 0 : $self->reader->E) - $self->_advance;
|
||||
my $gcode = sprintf "G1 %s%.5f F%.3f ; pressure discharge\n",
|
||||
$self->_extrusion_axis, $new_E, $F // $self->_unretract_speed;
|
||||
$gcode .= sprintf "G92 %s%.5f ; restore E\n", $self->_extrusion_axis, $self->reader->E
|
||||
if !$self->config->use_relative_e_distances;
|
||||
$self->_advance(0);
|
||||
|
||||
return $gcode;
|
||||
}
|
||||
|
||||
sub _unretract_speed {
|
||||
my ($self) = @_;
|
||||
return $self->config->get_at('retract_speed', $self->_tool) * 60;
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ sub BUILD {
|
|||
if $self->config->spiral_vase;
|
||||
|
||||
$self->_vibration_limit(Slic3r::GCode::VibrationLimit->new(config => $self->config))
|
||||
if $self->config->vibration_limit > 0;
|
||||
if $self->config->vibration_limit != 0;
|
||||
|
||||
$self->_arc_fitting(Slic3r::GCode::ArcFitting->new(config => $self->config))
|
||||
if $self->config->gcode_arcs;
|
||||
|
@ -208,7 +208,7 @@ sub export {
|
|||
}
|
||||
$self->process_layer($layer, [$copy]);
|
||||
}
|
||||
$self->flush_cooling_buffer;
|
||||
$self->flush_filters;
|
||||
$finished_objects++;
|
||||
}
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ sub export {
|
|||
}
|
||||
}
|
||||
}
|
||||
$self->flush_cooling_buffer;
|
||||
$self->flush_filters;
|
||||
}
|
||||
|
||||
# write end commands to file
|
||||
|
@ -529,28 +529,29 @@ sub _extrude_infill {
|
|||
return $gcode;
|
||||
}
|
||||
|
||||
sub flush_cooling_buffer {
|
||||
sub flush_filters {
|
||||
my ($self) = @_;
|
||||
print {$self->fh} $self->filter($self->_cooling_buffer->flush);
|
||||
|
||||
print {$self->fh} $self->filter($self->_cooling_buffer->flush, 1);
|
||||
}
|
||||
|
||||
sub filter {
|
||||
my ($self, $gcode) = @_;
|
||||
my ($self, $gcode, $flush) = @_;
|
||||
|
||||
# apply vibration limit if enabled;
|
||||
# this injects pauses according to time (thus depends on actual speeds)
|
||||
$gcode = $self->_vibration_limit->process($gcode)
|
||||
if $self->print->config->vibration_limit != 0;
|
||||
if defined $self->_vibration_limit;
|
||||
|
||||
# apply pressure regulation if enabled;
|
||||
# this depends on actual speeds
|
||||
$gcode = $self->_pressure_regulator->process($gcode)
|
||||
if $self->print->config->pressure_advance > 0;
|
||||
$gcode = $self->_pressure_regulator->process($gcode, $flush)
|
||||
if defined $self->_pressure_regulator;
|
||||
|
||||
# apply arc fitting if enabled;
|
||||
# this does not depend on speeds but changes G1 XY commands into G2/G2 IJ
|
||||
$gcode = $self->_arc_fitting->process($gcode)
|
||||
if $self->print->config->gcode_arcs;
|
||||
if defined $self->_arc_fitting;
|
||||
|
||||
return $gcode;
|
||||
}
|
||||
|
|
15
t/pressure.t
15
t/pressure.t
|
@ -9,7 +9,7 @@ BEGIN {
|
|||
|
||||
use List::Util qw();
|
||||
use Slic3r;
|
||||
use Slic3r::Geometry qw();
|
||||
use Slic3r::Geometry qw(epsilon);
|
||||
use Slic3r::Test;
|
||||
|
||||
{
|
||||
|
@ -18,21 +18,18 @@ use Slic3r::Test;
|
|||
$config->set('retract_length', [1]);
|
||||
|
||||
my $print = Slic3r::Test::init_print('20mm_cube', config => $config, duplicate => 2);
|
||||
my $retracted = 0;
|
||||
my $extruding_before_full_unretract = 0;
|
||||
my $retracted = $config->retract_length->[0];
|
||||
Slic3r::GCode::Reader->new->parse(Slic3r::Test::gcode($print), sub {
|
||||
my ($self, $cmd, $args, $info) = @_;
|
||||
|
||||
if ($info->{extruding} && $info->{dist_XY}) {
|
||||
$extruding_before_full_unretract if $retracted != 0;
|
||||
} elsif ($info->{extruding}) {
|
||||
$retracted += -$info->{dist_E};
|
||||
if ($info->{extruding} && !$info->{dist_XY}) {
|
||||
$retracted += $info->{dist_E};
|
||||
} elsif ($info->{retracting}) {
|
||||
$retracted += -$info->{dist_E};
|
||||
$retracted += $info->{dist_E};
|
||||
}
|
||||
});
|
||||
|
||||
ok !$extruding_before_full_unretract, 'not extruding before complete unretract';
|
||||
ok abs($retracted) < epsilon, 'all retractions are compensated';
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue