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:
Alessandro Ranellucci 2015-01-06 00:35:39 +01:00
parent 9fd0637990
commit 0f7933c4f9
3 changed files with 38 additions and 27 deletions

View file

@ -24,7 +24,7 @@ sub BUILD {
sub process { sub process {
my $self = shift; my $self = shift;
my ($gcode) = @_; my ($gcode, $flush) = @_;
my $new_gcode = ""; my $new_gcode = "";
@ -51,7 +51,7 @@ sub process {
if (abs($new_advance - $self->_advance) > 1E-5) { if (abs($new_advance - $self->_advance) > 1E-5) {
my $new_E = ($self->config->use_relative_e_distances ? 0 : $reader->E) + ($new_advance - $self->_advance); 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", $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 $new_gcode .= sprintf "G92 %s%.5f ; restore E\n", $self->_extrusion_axis, $reader->E
if !$self->config->use_relative_e_distances; if !$self->config->use_relative_e_distances;
$self->_advance($new_advance); $self->_advance($new_advance);
@ -61,20 +61,33 @@ sub process {
} }
} elsif (($info->{retracting} || $cmd eq 'G10') && $self->_advance != 0) { } elsif (($info->{retracting} || $cmd eq 'G10') && $self->_advance != 0) {
# We need to bring pressure to zero when retracting. # 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 .= $self->_discharge($args->{F});
$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 .= "$info->{raw}\n"; $new_gcode .= "$info->{raw}\n";
}); });
if ($flush) {
$new_gcode .= $self->_discharge;
}
return $new_gcode; 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) = @_; my ($self) = @_;
return $self->config->get_at('retract_speed', $self->_tool) * 60; return $self->config->get_at('retract_speed', $self->_tool) * 60;
} }

View file

@ -54,7 +54,7 @@ sub BUILD {
if $self->config->spiral_vase; if $self->config->spiral_vase;
$self->_vibration_limit(Slic3r::GCode::VibrationLimit->new(config => $self->config)) $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)) $self->_arc_fitting(Slic3r::GCode::ArcFitting->new(config => $self->config))
if $self->config->gcode_arcs; if $self->config->gcode_arcs;
@ -208,7 +208,7 @@ sub export {
} }
$self->process_layer($layer, [$copy]); $self->process_layer($layer, [$copy]);
} }
$self->flush_cooling_buffer; $self->flush_filters;
$finished_objects++; $finished_objects++;
} }
} }
@ -234,7 +234,7 @@ sub export {
} }
} }
} }
$self->flush_cooling_buffer; $self->flush_filters;
} }
# write end commands to file # write end commands to file
@ -529,28 +529,29 @@ sub _extrude_infill {
return $gcode; return $gcode;
} }
sub flush_cooling_buffer { sub flush_filters {
my ($self) = @_; my ($self) = @_;
print {$self->fh} $self->filter($self->_cooling_buffer->flush);
print {$self->fh} $self->filter($self->_cooling_buffer->flush, 1);
} }
sub filter { sub filter {
my ($self, $gcode) = @_; my ($self, $gcode, $flush) = @_;
# apply vibration limit if enabled; # apply vibration limit if enabled;
# this injects pauses according to time (thus depends on actual speeds) # this injects pauses according to time (thus depends on actual speeds)
$gcode = $self->_vibration_limit->process($gcode) $gcode = $self->_vibration_limit->process($gcode)
if $self->print->config->vibration_limit != 0; if defined $self->_vibration_limit;
# apply pressure regulation if enabled; # apply pressure regulation if enabled;
# this depends on actual speeds # this depends on actual speeds
$gcode = $self->_pressure_regulator->process($gcode) $gcode = $self->_pressure_regulator->process($gcode, $flush)
if $self->print->config->pressure_advance > 0; if defined $self->_pressure_regulator;
# apply arc fitting if enabled; # apply arc fitting if enabled;
# this does not depend on speeds but changes G1 XY commands into G2/G2 IJ # this does not depend on speeds but changes G1 XY commands into G2/G2 IJ
$gcode = $self->_arc_fitting->process($gcode) $gcode = $self->_arc_fitting->process($gcode)
if $self->print->config->gcode_arcs; if defined $self->_arc_fitting;
return $gcode; return $gcode;
} }

View file

@ -9,7 +9,7 @@ BEGIN {
use List::Util qw(); use List::Util qw();
use Slic3r; use Slic3r;
use Slic3r::Geometry qw(); use Slic3r::Geometry qw(epsilon);
use Slic3r::Test; use Slic3r::Test;
{ {
@ -18,21 +18,18 @@ use Slic3r::Test;
$config->set('retract_length', [1]); $config->set('retract_length', [1]);
my $print = Slic3r::Test::init_print('20mm_cube', config => $config, duplicate => 2); my $print = Slic3r::Test::init_print('20mm_cube', config => $config, duplicate => 2);
my $retracted = 0; my $retracted = $config->retract_length->[0];
my $extruding_before_full_unretract = 0;
Slic3r::GCode::Reader->new->parse(Slic3r::Test::gcode($print), sub { Slic3r::GCode::Reader->new->parse(Slic3r::Test::gcode($print), sub {
my ($self, $cmd, $args, $info) = @_; my ($self, $cmd, $args, $info) = @_;
if ($info->{extruding} && $info->{dist_XY}) { if ($info->{extruding} && !$info->{dist_XY}) {
$extruding_before_full_unretract if $retracted != 0; $retracted += $info->{dist_E};
} elsif ($info->{extruding}) {
$retracted += -$info->{dist_E};
} elsif ($info->{retracting}) { } 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';
} }