New experimental feature for pressure management. Credits to @llluis for the original implementation. #1203 #1677 #2018
This commit is contained in:
parent
5a382f0200
commit
ff9b53260d
@ -139,6 +139,8 @@ The author of the Silk icon set is Mark James.
|
|||||||
--gcode-comments Make G-code verbose by adding comments (default: no)
|
--gcode-comments Make G-code verbose by adding comments (default: no)
|
||||||
--vibration-limit Limit the frequency of moves on X and Y axes (Hz, set zero to disable;
|
--vibration-limit Limit the frequency of moves on X and Y axes (Hz, set zero to disable;
|
||||||
default: 0)
|
default: 0)
|
||||||
|
--pressure-advance Adjust pressure using the experimental advance algorithm (K constant,
|
||||||
|
set zero to disable; default: 0)
|
||||||
|
|
||||||
Filament options:
|
Filament options:
|
||||||
--filament-diameter Diameter in mm of your raw filament (default: 3)
|
--filament-diameter Diameter in mm of your raw filament (default: 3)
|
||||||
|
@ -51,6 +51,7 @@ use Slic3r::GCode::CoolingBuffer;
|
|||||||
use Slic3r::GCode::Layer;
|
use Slic3r::GCode::Layer;
|
||||||
use Slic3r::GCode::MotionPlanner;
|
use Slic3r::GCode::MotionPlanner;
|
||||||
use Slic3r::GCode::PlaceholderParser;
|
use Slic3r::GCode::PlaceholderParser;
|
||||||
|
use Slic3r::GCode::PressureRegulator;
|
||||||
use Slic3r::GCode::Reader;
|
use Slic3r::GCode::Reader;
|
||||||
use Slic3r::GCode::SpiralVase;
|
use Slic3r::GCode::SpiralVase;
|
||||||
use Slic3r::GCode::VibrationLimit;
|
use Slic3r::GCode::VibrationLimit;
|
||||||
|
@ -11,6 +11,7 @@ has 'origin' => (is => 'ro', default => sub { Slic3r::Poi
|
|||||||
has 'spiralvase' => (is => 'lazy');
|
has 'spiralvase' => (is => 'lazy');
|
||||||
has 'vibration_limit' => (is => 'lazy');
|
has 'vibration_limit' => (is => 'lazy');
|
||||||
has 'arc_fitting' => (is => 'lazy');
|
has 'arc_fitting' => (is => 'lazy');
|
||||||
|
has 'pressure_regulator' => (is => 'lazy');
|
||||||
has 'skirt_done' => (is => 'rw', default => sub { {} }); # print_z => 1
|
has 'skirt_done' => (is => 'rw', default => sub { {} }); # print_z => 1
|
||||||
has 'brim_done' => (is => 'rw');
|
has 'brim_done' => (is => 'rw');
|
||||||
has 'second_layer_things_done' => (is => 'rw');
|
has 'second_layer_things_done' => (is => 'rw');
|
||||||
@ -40,6 +41,14 @@ sub _build_arc_fitting {
|
|||||||
: undef;
|
: undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub _build_pressure_regulator {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
return $self->print->config->pressure_advance > 0
|
||||||
|
? Slic3r::GCode::PressureRegulator->new(config => $self->print->config)
|
||||||
|
: undef;
|
||||||
|
}
|
||||||
|
|
||||||
sub process_layer {
|
sub process_layer {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my ($layer, $object_copies) = @_;
|
my ($layer, $object_copies) = @_;
|
||||||
@ -197,6 +206,10 @@ sub process_layer {
|
|||||||
$gcode = $self->vibration_limit->process($gcode)
|
$gcode = $self->vibration_limit->process($gcode)
|
||||||
if $self->print->config->vibration_limit != 0;
|
if $self->print->config->vibration_limit != 0;
|
||||||
|
|
||||||
|
# apply pressure regulation if enabled
|
||||||
|
$gcode = $self->pressure_regulator->process($gcode)
|
||||||
|
if $self->print->config->pressure_advance > 0;
|
||||||
|
|
||||||
# apply arc fitting if enabled
|
# apply arc fitting if enabled
|
||||||
$gcode = $self->arc_fitting->process($gcode)
|
$gcode = $self->arc_fitting->process($gcode)
|
||||||
if $self->print->config->gcode_arcs;
|
if $self->print->config->gcode_arcs;
|
||||||
|
78
lib/Slic3r/GCode/PressureRegulator.pm
Normal file
78
lib/Slic3r/GCode/PressureRegulator.pm
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
package Slic3r::GCode::PressureRegulator;
|
||||||
|
use Moo;
|
||||||
|
|
||||||
|
has 'config' => (is => 'ro', required => 1);
|
||||||
|
has 'enable' => (is => 'rw', default => sub { 0 });
|
||||||
|
has 'reader' => (is => 'ro', default => sub { Slic3r::GCode::Reader->new });
|
||||||
|
has '_extrusion_axis' => (is => 'rw', default => sub { "E" });
|
||||||
|
has '_tool' => (is => 'rw', default => sub { 0 });
|
||||||
|
has '_advance' => (is => 'rw', default => sub { 0 }); # extra E injected
|
||||||
|
|
||||||
|
use Slic3r::Geometry qw(epsilon);
|
||||||
|
|
||||||
|
# Acknowledgements:
|
||||||
|
# The advance algorithm was proposed by Matthew Roberts.
|
||||||
|
# The initial work on this Slic3r feature was done by Luís Andrade (lluis)
|
||||||
|
|
||||||
|
sub BUILD {
|
||||||
|
my ($self) = @_;
|
||||||
|
|
||||||
|
$self->reader->apply_print_config($self->config);
|
||||||
|
$self->_extrusion_axis($self->config->get_extrusion_axis);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub process {
|
||||||
|
my $self = shift;
|
||||||
|
my ($gcode) = @_;
|
||||||
|
|
||||||
|
my $new_gcode = "";
|
||||||
|
|
||||||
|
$self->reader->parse($gcode, sub {
|
||||||
|
my ($reader, $cmd, $args, $info) = @_;
|
||||||
|
|
||||||
|
if ($cmd =~ /^T(\d+)/) {
|
||||||
|
$self->_tool($1);
|
||||||
|
} elsif ($info->{extruding} && $info->{dist_XY} > 0) {
|
||||||
|
# This is a print move.
|
||||||
|
if (exists $args->{F}) {
|
||||||
|
# We are setting a (potentially) new speed, so we calculate the new advance amount.
|
||||||
|
|
||||||
|
# First calculate relative flow rate (mm of filament over mm of travel)
|
||||||
|
my $rel_flow_rate = $info->{dist_E} / $info->{dist_XY};
|
||||||
|
|
||||||
|
# Then calculate absolute flow rate (mm/sec of feedstock)
|
||||||
|
my $flow_rate = $rel_flow_rate * $args->{F} / 60;
|
||||||
|
|
||||||
|
# And finally calculate advance by using the user-configured K factor.
|
||||||
|
my $new_advance = $self->config->pressure_advance * ($flow_rate**2);
|
||||||
|
|
||||||
|
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;
|
||||||
|
$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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} 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 .= "$info->{raw}\n";
|
||||||
|
});
|
||||||
|
|
||||||
|
return $new_gcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub unretract_speed {
|
||||||
|
my ($self) = @_;
|
||||||
|
return $self->config->get_at('retract_speed', $self->_tool) * 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
@ -894,7 +894,7 @@ sub build {
|
|||||||
$self->init_config_options(qw(
|
$self->init_config_options(qw(
|
||||||
bed_shape z_offset
|
bed_shape z_offset
|
||||||
gcode_flavor use_relative_e_distances
|
gcode_flavor use_relative_e_distances
|
||||||
use_firmware_retraction vibration_limit
|
use_firmware_retraction pressure_advance vibration_limit
|
||||||
start_gcode end_gcode layer_gcode toolchange_gcode
|
start_gcode end_gcode layer_gcode toolchange_gcode
|
||||||
nozzle_diameter extruder_offset
|
nozzle_diameter extruder_offset
|
||||||
retract_length retract_lift retract_speed retract_restart_extra retract_before_travel retract_layer_change wipe
|
retract_length retract_lift retract_speed retract_restart_extra retract_before_travel retract_layer_change wipe
|
||||||
@ -970,6 +970,7 @@ sub build {
|
|||||||
{
|
{
|
||||||
my $optgroup = $page->new_optgroup('Advanced');
|
my $optgroup = $page->new_optgroup('Advanced');
|
||||||
$optgroup->append_single_option_line('use_firmware_retraction');
|
$optgroup->append_single_option_line('use_firmware_retraction');
|
||||||
|
$optgroup->append_single_option_line('pressure_advance');
|
||||||
$optgroup->append_single_option_line('vibration_limit');
|
$optgroup->append_single_option_line('vibration_limit');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -667,7 +667,7 @@ sub write_gcode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# write end commands to file
|
# write end commands to file
|
||||||
print $fh $gcodegen->retract;
|
print $fh $gcodegen->retract; # TODO: process this retract through PressureRegulator in order to discharge fully
|
||||||
print $fh $gcodegen->writer->set_fan(0);
|
print $fh $gcodegen->writer->set_fan(0);
|
||||||
printf $fh "%s\n", $gcodegen->placeholder_parser->process($self->config->end_gcode);
|
printf $fh "%s\n", $gcodegen->placeholder_parser->process($self->config->end_gcode);
|
||||||
print $fh $gcodegen->writer->update_progress($gcodegen->layer_count, $gcodegen->layer_count, 1); # 100%
|
print $fh $gcodegen->writer->update_progress($gcodegen->layer_count, $gcodegen->layer_count, 1); # 100%
|
||||||
|
@ -291,6 +291,8 @@ $j
|
|||||||
--gcode-comments Make G-code verbose by adding comments (default: no)
|
--gcode-comments Make G-code verbose by adding comments (default: no)
|
||||||
--vibration-limit Limit the frequency of moves on X and Y axes (Hz, set zero to disable;
|
--vibration-limit Limit the frequency of moves on X and Y axes (Hz, set zero to disable;
|
||||||
default: $config->{vibration_limit})
|
default: $config->{vibration_limit})
|
||||||
|
--pressure-advance Adjust pressure using the experimental advance algorithm (K constant,
|
||||||
|
set zero to disable; default: $config->{pressure_advance})
|
||||||
|
|
||||||
Filament options:
|
Filament options:
|
||||||
--filament-diameter Diameter in mm of your raw filament (default: $config->{filament_diameter}->[0])
|
--filament-diameter Diameter in mm of your raw filament (default: $config->{filament_diameter}->[0])
|
||||||
|
@ -550,6 +550,12 @@ PrintConfigDef::build_def() {
|
|||||||
Options["post_process"].full_width = true;
|
Options["post_process"].full_width = true;
|
||||||
Options["post_process"].height = 60;
|
Options["post_process"].height = 60;
|
||||||
|
|
||||||
|
Options["pressure_advance"].type = coFloat;
|
||||||
|
Options["pressure_advance"].label = "Pressure advance";
|
||||||
|
Options["pressure_advance"].tooltip = "When set to a non-zero value, this experimental option enables pressure regulation. It's the K constant for the advance algorithm that pushes more or less filament upon speed changes. It's useful for Bowden-tube extruders. Reasonable values are in range 0-10.";
|
||||||
|
Options["pressure_advance"].cli = "pressure-advance=f";
|
||||||
|
Options["pressure_advance"].min = 0;
|
||||||
|
|
||||||
Options["raft_layers"].type = coInt;
|
Options["raft_layers"].type = coInt;
|
||||||
Options["raft_layers"].label = "Raft layers";
|
Options["raft_layers"].label = "Raft layers";
|
||||||
Options["raft_layers"].category = "Support material";
|
Options["raft_layers"].category = "Support material";
|
||||||
|
@ -319,6 +319,7 @@ class GCodeConfig : public virtual StaticPrintConfig
|
|||||||
ConfigOptionFloats filament_diameter;
|
ConfigOptionFloats filament_diameter;
|
||||||
ConfigOptionBool gcode_comments;
|
ConfigOptionBool gcode_comments;
|
||||||
ConfigOptionEnum<GCodeFlavor> gcode_flavor;
|
ConfigOptionEnum<GCodeFlavor> gcode_flavor;
|
||||||
|
ConfigOptionFloat pressure_advance;
|
||||||
ConfigOptionFloats retract_length;
|
ConfigOptionFloats retract_length;
|
||||||
ConfigOptionFloats retract_length_toolchange;
|
ConfigOptionFloats retract_length_toolchange;
|
||||||
ConfigOptionFloats retract_lift;
|
ConfigOptionFloats retract_lift;
|
||||||
@ -337,6 +338,7 @@ class GCodeConfig : public virtual StaticPrintConfig
|
|||||||
this->filament_diameter.values[0] = 3;
|
this->filament_diameter.values[0] = 3;
|
||||||
this->gcode_comments.value = false;
|
this->gcode_comments.value = false;
|
||||||
this->gcode_flavor.value = gcfRepRap;
|
this->gcode_flavor.value = gcfRepRap;
|
||||||
|
this->pressure_advance.value = 0;
|
||||||
this->retract_length.values.resize(1);
|
this->retract_length.values.resize(1);
|
||||||
this->retract_length.values[0] = 1;
|
this->retract_length.values[0] = 1;
|
||||||
this->retract_length_toolchange.values.resize(1);
|
this->retract_length_toolchange.values.resize(1);
|
||||||
@ -360,6 +362,7 @@ class GCodeConfig : public virtual StaticPrintConfig
|
|||||||
if (opt_key == "filament_diameter") return &this->filament_diameter;
|
if (opt_key == "filament_diameter") return &this->filament_diameter;
|
||||||
if (opt_key == "gcode_comments") return &this->gcode_comments;
|
if (opt_key == "gcode_comments") return &this->gcode_comments;
|
||||||
if (opt_key == "gcode_flavor") return &this->gcode_flavor;
|
if (opt_key == "gcode_flavor") return &this->gcode_flavor;
|
||||||
|
if (opt_key == "pressure_advance") return &this->pressure_advance;
|
||||||
if (opt_key == "retract_length") return &this->retract_length;
|
if (opt_key == "retract_length") return &this->retract_length;
|
||||||
if (opt_key == "retract_length_toolchange") return &this->retract_length_toolchange;
|
if (opt_key == "retract_length_toolchange") return &this->retract_length_toolchange;
|
||||||
if (opt_key == "retract_lift") return &this->retract_lift;
|
if (opt_key == "retract_lift") return &this->retract_lift;
|
||||||
|
Loading…
Reference in New Issue
Block a user