Add volumetric extrusion limit (#17017)

This commit is contained in:
MoellerDi
2020-06-08 10:24:46 +02:00
committed by GitHub
parent 8994cc8b26
commit bac760207c
9 changed files with 176 additions and 25 deletions

View File

@ -37,7 +37,7 @@
*/
// Change EEPROM version if the structure changes
#define EEPROM_VERSION "V79"
#define EEPROM_VERSION "V80"
#define EEPROM_OFFSET 100
// Check the integrity of data offsets.
@ -320,8 +320,9 @@ typedef struct SettingsDataStruct {
//
// !NO_VOLUMETRIC
//
bool parser_volumetric_enabled; // M200 D parser.volumetric_enabled
bool parser_volumetric_enabled; // M200 S parser.volumetric_enabled
float planner_filament_size[EXTRUDERS]; // M200 T D planner.filament_size[]
float planner_volumetric_extruder_limit[EXTRUDERS]; // M200 T L planner.volumetric_extruder_limit[]
//
// HAS_TRINAMIC_CONFIG
@ -935,12 +936,20 @@ void MarlinSettings::postprocess() {
EEPROM_WRITE(parser.volumetric_enabled);
EEPROM_WRITE(planner.filament_size);
#if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
EEPROM_WRITE(planner.volumetric_extruder_limit);
#else
dummyf = DEFAULT_VOLUMETRIC_EXTRUDER_LIMIT;
for (uint8_t q = EXTRUDERS; q--;) EEPROM_WRITE(dummyf);
#endif
#else
const bool volumetric_enabled = false;
dummyf = DEFAULT_NOMINAL_FILAMENT_DIA;
EEPROM_WRITE(volumetric_enabled);
dummyf = DEFAULT_NOMINAL_FILAMENT_DIA;
for (uint8_t q = EXTRUDERS; q--;) EEPROM_WRITE(dummyf);
dummyf = DEFAULT_VOLUMETRIC_EXTRUDER_LIMIT;
for (uint8_t q = EXTRUDERS; q--;) EEPROM_WRITE(dummyf);
#endif
@ -1787,6 +1796,9 @@ void MarlinSettings::postprocess() {
struct {
bool volumetric_enabled;
float filament_size[EXTRUDERS];
#if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
float volumetric_extruder_limit[EXTRUDERS];
#endif
} storage;
_FIELD_TEST(parser_volumetric_enabled);
@ -1796,6 +1808,9 @@ void MarlinSettings::postprocess() {
if (!validating) {
parser.volumetric_enabled = storage.volumetric_enabled;
COPY(planner.filament_size, storage.filament_size);
#if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
COPY(planner.volumetric_extruder_limit, storage.volumetric_extruder_limit);
#endif
}
#endif
}
@ -2598,6 +2613,10 @@ void MarlinSettings::reset() {
parser.volumetric_enabled = ENABLED(VOLUMETRIC_DEFAULT_ON);
LOOP_L_N(q, COUNT(planner.filament_size))
planner.filament_size[q] = DEFAULT_NOMINAL_FILAMENT_DIA;
#if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
LOOP_L_N(q, COUNT(planner.volumetric_extruder_limit))
planner.volumetric_extruder_limit[q] = DEFAULT_VOLUMETRIC_EXTRUDER_LIMIT;
#endif
#endif
endstops.enable_globally(ENABLED(ENDSTOPS_ALWAYS_ON_DEFAULT));
@ -2750,7 +2769,7 @@ void MarlinSettings::reset() {
SERIAL_EOL();
#if DISABLED(NO_VOLUMETRICS)
#if EXTRUDERS && DISABLED(NO_VOLUMETRICS)
/**
* Volumetric extrusion M200
@ -2765,20 +2784,26 @@ void MarlinSettings::reset() {
#if EXTRUDERS == 1
CONFIG_ECHO_START();
SERIAL_ECHOLNPAIR(" M200 D", LINEAR_UNIT(planner.filament_size[0]));
#elif EXTRUDERS
SERIAL_ECHOLNPAIR(" M200 S", int(parser.volumetric_enabled)
, " D", LINEAR_UNIT(planner.filament_size[0]),
#if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
, " L", LINEAR_UNIT(planner.volumetric_extruder_limit[0])
#endif
);
#else
LOOP_L_N(i, EXTRUDERS) {
CONFIG_ECHO_START();
SERIAL_ECHOPGM(" M200");
if (i) SERIAL_ECHOPAIR_P(SP_T_STR, int(i));
SERIAL_ECHOLNPAIR(" D", LINEAR_UNIT(planner.filament_size[i]));
SERIAL_ECHOLNPAIR(" M200 T", int(i)
, " D", LINEAR_UNIT(planner.filament_size[i])
#if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
, " L", LINEAR_UNIT(planner.volumetric_extruder_limit[i])
#endif
);
}
CONFIG_ECHO_START();
SERIAL_ECHOLNPAIR(" M200 S", int(parser.volumetric_enabled));
#endif
if (!parser.volumetric_enabled)
CONFIG_ECHO_MSG(" M200 D0");
#endif // !NO_VOLUMETRICS
#endif // EXTRUDERS && !NO_VOLUMETRICS
CONFIG_ECHO_HEADING("Steps per unit:");
report_M92(!forReplay);

View File

@ -171,6 +171,11 @@ float Planner::steps_to_mm[XYZE_N]; // (mm) Millimeters per step
Planner::volumetric_multiplier[EXTRUDERS]; // Reciprocal of cross-sectional area of filament (in mm^2). Pre-calculated to reduce computation in the planner
#endif
#if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
float Planner::volumetric_extruder_limit[EXTRUDERS], // max mm^3/sec the extruder is able to handle
Planner::volumetric_extruder_feedrate_limit[EXTRUDERS]; // pre calculated extruder feedrate limit based on volumetric_extruder_limit; pre-calculated to reduce computation in the planner
#endif
#if HAS_LEVELING
bool Planner::leveling_active = false; // Flag that auto bed leveling is enabled
#if ABL_PLANAR
@ -1407,10 +1412,28 @@ void Planner::check_axes_activity() {
volumetric_multiplier[i] = calculate_volumetric_multiplier(filament_size[i]);
refresh_e_factor(i);
}
#if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
calculate_volumetric_extruder_limits(); // update volumetric_extruder_limits as well.
#endif
}
#endif // !NO_VOLUMETRICS
#if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
/**
* Convert volumetric based limits into pre calculated extruder feedrate limits.
*/
void Planner::calculate_volumetric_extruder_limit(const uint8_t e) {
const float &lim = volumetric_extruder_limit[e], &siz = filament_size[e];
volumetric_extruder_feedrate_limit[e] = (lim && siz) ? lim / CIRCLE_AREA(siz * 0.5f) : 0;
}
void Planner::calculate_volumetric_extruder_limits() {
LOOP_L_N(e, EXTRUDERS) calculate_volumetric_extruder_limit(e);
}
#endif
#if ENABLED(FILAMENT_WIDTH_SENSOR)
/**
* Convert the ratio value given by the filament width sensor
@ -2077,10 +2100,33 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
if (mixer.get_current_vtool() == MIXER_AUTORETRACT_TOOL)
current_speed.e *= MIXING_STEPPERS;
#endif
const feedRate_t cs = ABS(current_speed.e),
max_fr = settings.max_feedrate_mm_s[E_AXIS_N(extruder)]
* TERN(HAS_MIXER_SYNC_CHANNEL, MIXING_STEPPERS, 1);
if (cs > max_fr) NOMORE(speed_factor, max_fr / cs);
if (cs > max_fr) NOMORE(speed_factor, max_fr / cs); //respect max feedrate on any movement (doesn't matter if E axes only or not)
#if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
const feedRate_t max_vfr = volumetric_extruder_feedrate_limit[extruder]
* TERN(HAS_MIXER_SYNC_CHANNEL, MIXING_STEPPERS, 1);
// TODO: Doesn't work properly for joined segments. Set MIN_STEPS_PER_SEGMENT 1 as workaround.
if (block->steps.a || block->steps.b || block->steps.c) {
if (max_vfr > 0 && cs > max_vfr) {
NOMORE(speed_factor, max_vfr / cs); // respect volumetric extruder limit (if any)
/* <-- add a slash to enable
SERIAL_ECHOPAIR("volumetric extruder limit enforced: ", (cs * CIRCLE_AREA(filament_size[extruder] * 0.5f)));
SERIAL_ECHOPAIR(" mm^3/s (", cs);
SERIAL_ECHOPAIR(" mm/s) limited to ", (max_vfr * CIRCLE_AREA(filament_size[extruder] * 0.5f)));
SERIAL_ECHOPAIR(" mm^3/s (", max_vfr);
SERIAL_ECHOLNPGM(" mm/s)");
//*/
}
}
#endif
}
#endif

View File

@ -333,6 +333,11 @@ class Planner {
// May be auto-adjusted by a filament width sensor
#endif
#if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
static float volumetric_extruder_limit[EXTRUDERS], // Maximum mm^3/sec the extruder can handle
volumetric_extruder_feedrate_limit[EXTRUDERS]; // Feedrate limit (mm/s) calculated from volume limit
#endif
static planner_settings_t settings;
#if ENABLED(LASER_POWER_INLINE)
@ -473,9 +478,6 @@ class Planner {
// Manage fans, paste pressure, etc.
static void check_axes_activity();
// Update multipliers based on new diameter measurements
static void calculate_volumetric_multipliers();
#if ENABLED(FILAMENT_WIDTH_SENSOR)
void apply_filament_width_sensor(const int8_t encoded_ratio);
@ -489,8 +491,18 @@ class Planner {
#if DISABLED(NO_VOLUMETRICS)
// Update multipliers based on new diameter measurements
static void calculate_volumetric_multipliers();
#if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
// Update pre calculated extruder feedrate limits based on volumetric values
static void calculate_volumetric_extruder_limit(const uint8_t e);
static void calculate_volumetric_extruder_limits();
#endif
FORCE_INLINE static void set_filament_size(const uint8_t e, const float &v) {
filament_size[e] = v;
if (v > 0) volumetric_area_nominal = CIRCLE_AREA(v * 0.5); //TODO: should it be per extruder
// make sure all extruders have some sane value for the filament size
LOOP_L_N(i, COUNT(filament_size))
if (!filament_size[i]) filament_size[i] = DEFAULT_NOMINAL_FILAMENT_DIA;
@ -498,6 +510,13 @@ class Planner {
#endif
#if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
FORCE_INLINE static void set_volumetric_extruder_limit(const uint8_t e, const float &v) {
volumetric_extruder_limit[e] = v;
calculate_volumetric_extruder_limit(e);
}
#endif
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
/**