1
0
mirror of https://github.com/MarlinFirmware/Marlin.git synced 2024-11-27 13:56:24 +00:00

Make FWRetract class for 2.0.x parity

This commit is contained in:
Scott Lahteine 2018-01-04 16:42:56 -06:00
parent 518d9beb83
commit e7bf7e6031
7 changed files with 352 additions and 238 deletions

View File

@ -136,7 +136,6 @@
#if ENABLED(ULTRA_LCD)
extern char lcd_status_message[];
#endif
inline void sync_plan_position_e() { planner.set_e_position_mm(current_position[E_AXIS]); }
// Private functions

View File

@ -179,6 +179,16 @@ void disable_e_stepper(const uint8_t e);
void disable_e_steppers();
void disable_all_steppers();
void sync_plan_position();
void sync_plan_position_e();
#if IS_KINEMATIC
void sync_plan_position_kinematic();
#define SYNC_PLAN_POSITION_KINEMATIC() sync_plan_position_kinematic()
#else
#define SYNC_PLAN_POSITION_KINEMATIC() sync_plan_position()
#endif
void FlushSerialRequestResend();
void ok_to_send();
@ -449,18 +459,6 @@ void report_current_position();
extern int lpq_len;
#endif
#if ENABLED(FWRETRACT)
extern bool autoretract_enabled; // M209 S - Autoretract switch
extern float retract_length, // M207 S - G10 Retract length
retract_feedrate_mm_s, // M207 F - G10 Retract feedrate
retract_zlift, // M207 Z - G10 Retract hop size
retract_recover_length, // M208 S - G11 Recover length
retract_recover_feedrate_mm_s, // M208 F - G11 Recover feedrate
swap_retract_length, // M207 W - G10 Swap Retract length
swap_retract_recover_length, // M208 W - G11 Swap Recover length
swap_retract_recover_feedrate_mm_s; // M208 R - G11 Swap Recover feedrate
#endif
// Print job timer
#if ENABLED(PRINTCOUNTER)
extern PrintCounter print_job_timer;

View File

@ -277,6 +277,10 @@
#include "planner_bezier.h"
#endif
#if ENABLED(FWRETRACT)
#include "fwretract.h"
#endif
#if HAS_BUZZER && DISABLED(LCD_USE_I2C_BUZZER)
#include "buzzer.h"
#endif
@ -573,24 +577,6 @@ uint8_t target_extruder;
baricuda_e_to_p_pressure = 0;
#endif
#if ENABLED(FWRETRACT) // Initialized by settings.load()...
bool autoretract_enabled, // M209 S - Autoretract switch
retracted[EXTRUDERS] = { false }; // Which extruders are currently retracted
float retract_length, // M207 S - G10 Retract length
retract_feedrate_mm_s, // M207 F - G10 Retract feedrate
retract_zlift, // M207 Z - G10 Retract hop size
retract_recover_length, // M208 S - G11 Recover length
retract_recover_feedrate_mm_s, // M208 F - G11 Recover feedrate
swap_retract_length, // M207 W - G10 Swap Retract length
swap_retract_recover_length, // M208 W - G11 Swap Recover length
swap_retract_recover_feedrate_mm_s; // M208 R - G11 Swap Recover feedrate
#if EXTRUDERS > 1
bool retracted_swap[EXTRUDERS] = { false }; // Which extruders are swap-retracted
#else
constexpr bool retracted_swap[1] = { false };
#endif
#endif // FWRETRACT
#if HAS_POWER_SWITCH
bool powersupply_on =
#if ENABLED(PS_DEFAULT_OFF)
@ -782,22 +768,15 @@ void sync_plan_position() {
#endif
planner.set_position_mm(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
}
inline void sync_plan_position_e() { planner.set_e_position_mm(current_position[E_AXIS]); }
void sync_plan_position_e() { planner.set_e_position_mm(current_position[E_AXIS]); }
#if IS_KINEMATIC
inline void sync_plan_position_kinematic() {
#if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("sync_plan_position_kinematic", current_position);
#endif
planner.set_position_mm_kinematic(current_position);
}
#define SYNC_PLAN_POSITION_KINEMATIC() sync_plan_position_kinematic()
#else
#define SYNC_PLAN_POSITION_KINEMATIC() sync_plan_position()
#endif
#if ENABLED(SDSUPPORT)
@ -3099,129 +3078,6 @@ static void homeaxis(const AxisEnum axis) {
#endif
} // homeaxis()
#if ENABLED(FWRETRACT)
/**
* Retract or recover according to firmware settings
*
* This function handles retract/recover moves for G10 and G11,
* plus auto-retract moves sent from G0/G1 when E-only moves are done.
*
* To simplify the logic, doubled retract/recover moves are ignored.
*
* Note: Z lift is done transparently to the planner. Aborting
* a print between G10 and G11 may corrupt the Z position.
*
* Note: Auto-retract will apply the set Z hop in addition to any Z hop
* included in the G-code. Use M207 Z0 to to prevent double hop.
*/
void retract(const bool retracting
#if EXTRUDERS > 1
, bool swapping = false
#endif
) {
static float hop_amount = 0.0; // Total amount lifted, for use in recover
// Prevent two retracts or recovers in a row
if (retracted[active_extruder] == retracting) return;
// Prevent two swap-retract or recovers in a row
#if EXTRUDERS > 1
// Allow G10 S1 only after G10
if (swapping && retracted_swap[active_extruder] == retracting) return;
// G11 priority to recover the long retract if activated
if (!retracting) swapping = retracted_swap[active_extruder];
#else
const bool swapping = false;
#endif
/* // debugging
SERIAL_ECHOLNPAIR("retracting ", retracting);
SERIAL_ECHOLNPAIR("swapping ", swapping);
SERIAL_ECHOLNPAIR("active extruder ", active_extruder);
for (uint8_t i = 0; i < EXTRUDERS; ++i) {
SERIAL_ECHOPAIR("retracted[", i);
SERIAL_ECHOLNPAIR("] ", retracted[i]);
SERIAL_ECHOPAIR("retracted_swap[", i);
SERIAL_ECHOLNPAIR("] ", retracted_swap[i]);
}
SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]);
SERIAL_ECHOLNPAIR("hop_amount ", hop_amount);
//*/
const bool has_zhop = retract_zlift > 0.01; // Is there a hop set?
const float old_feedrate_mm_s = feedrate_mm_s;
// The current position will be the destination for E and Z moves
set_destination_from_current();
stepper.synchronize(); // Wait for buffered moves to complete
const float renormalize = 1.0 / planner.e_factor[active_extruder];
if (retracting) {
// Retract by moving from a faux E position back to the current E position
feedrate_mm_s = retract_feedrate_mm_s;
current_position[E_AXIS] += (swapping ? swap_retract_length : retract_length) * renormalize;
sync_plan_position_e();
prepare_move_to_destination();
// Is a Z hop set, and has the hop not yet been done?
if (has_zhop && !hop_amount) {
hop_amount += retract_zlift; // Carriage is raised for retraction hop
feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS]; // Z feedrate to max
current_position[Z_AXIS] -= retract_zlift; // Pretend current pos is lower. Next move raises Z.
SYNC_PLAN_POSITION_KINEMATIC(); // Set the planner to the new position
prepare_move_to_destination(); // Raise up to the old current pos
feedrate_mm_s = retract_feedrate_mm_s; // Restore feedrate
}
}
else {
// If a hop was done and Z hasn't changed, undo the Z hop
if (hop_amount) {
current_position[Z_AXIS] += retract_zlift; // Pretend current pos is lower. Next move raises Z.
SYNC_PLAN_POSITION_KINEMATIC(); // Set the planner to the new position
feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS]; // Z feedrate to max
prepare_move_to_destination(); // Raise up to the old current pos
hop_amount = 0.0; // Clear hop
}
// A retract multiplier has been added here to get faster swap recovery
feedrate_mm_s = swapping ? swap_retract_recover_feedrate_mm_s : retract_recover_feedrate_mm_s;
const float move_e = swapping ? swap_retract_length + swap_retract_recover_length : retract_length + retract_recover_length;
current_position[E_AXIS] -= move_e * renormalize;
sync_plan_position_e();
prepare_move_to_destination(); // Recover E
}
feedrate_mm_s = old_feedrate_mm_s; // Restore original feedrate
retracted[active_extruder] = retracting; // Active extruder now retracted / recovered
// If swap retract/recover update the retracted_swap flag too
#if EXTRUDERS > 1
if (swapping) retracted_swap[active_extruder] = retracting;
#endif
/* // debugging
SERIAL_ECHOLNPAIR("retracting ", retracting);
SERIAL_ECHOLNPAIR("swapping ", swapping);
SERIAL_ECHOLNPAIR("active_extruder ", active_extruder);
for (uint8_t i = 0; i < EXTRUDERS; ++i) {
SERIAL_ECHOPAIR("retracted[", i);
SERIAL_ECHOLNPAIR("] ", retracted[i]);
SERIAL_ECHOPAIR("retracted_swap[", i);
SERIAL_ECHOLNPAIR("] ", retracted_swap[i]);
}
SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]);
SERIAL_ECHOLNPAIR("hop_amount ", hop_amount);
//*/
}
#endif // FWRETRACT
#if ENABLED(MIXING_EXTRUDER)
void normalize_mix() {
@ -3355,14 +3211,14 @@ inline void gcode_G0_G1(
#if ENABLED(FWRETRACT)
if (MIN_AUTORETRACT <= MAX_AUTORETRACT) {
// When M209 Autoretract is enabled, convert E-only moves to firmware retract/recover moves
if (autoretract_enabled && parser.seen('E') && !(parser.seen('X') || parser.seen('Y') || parser.seen('Z'))) {
// When M209 Autoretract is enabled, convert E-only moves to firmware retract/prime moves
if (fwretract.autoretract_enabled && parser.seen('E') && !(parser.seen('X') || parser.seen('Y') || parser.seen('Z'))) {
const float echange = destination[E_AXIS] - current_position[E_AXIS];
// Is this a retract or recover move?
if (WITHIN(FABS(echange), MIN_AUTORETRACT, MAX_AUTORETRACT) && retracted[active_extruder] == (echange > 0.0)) {
current_position[E_AXIS] = destination[E_AXIS]; // Hide a G1-based retract/recover from calculations
// Is this a retract or prime move?
if (WITHIN(FABS(echange), MIN_AUTORETRACT, MAX_AUTORETRACT) && fwretract.retracted[active_extruder] == (echange > 0.0)) {
current_position[E_AXIS] = destination[E_AXIS]; // Hide a G1-based retract/prime from calculations
sync_plan_position_e(); // AND from the planner
return retract(echange < 0.0); // Firmware-based retract/recover (double-retract ignored)
return fwretract.retract(echange < 0.0); // Firmware-based retract/prime (double-retract ignored)
}
}
}
@ -3558,9 +3414,9 @@ inline void gcode_G4() {
inline void gcode_G10() {
#if EXTRUDERS > 1
const bool rs = parser.boolval('S');
retracted_swap[active_extruder] = rs; // Use 'S' for swap, default to false
fwretract.retracted_swap[active_extruder] = rs; // Use 'S' for swap, default to false
#endif
retract(true
fwretract.retract(true
#if EXTRUDERS > 1
, rs
#endif
@ -3570,7 +3426,7 @@ inline void gcode_G4() {
/**
* G11 - Recover filament according to settings of M208
*/
inline void gcode_G11() { retract(false); }
inline void gcode_G11() { fwretract.retract(false); }
#endif // FWRETRACT
@ -6786,8 +6642,8 @@ inline void gcode_M17() {
// Intelligent resuming
#if ENABLED(FWRETRACT)
// If retracted before goto pause
if (retracted[active_extruder])
do_pause_e_move(-retract_length, retract_feedrate_mm_s);
if (fwretract.retracted[active_extruder])
do_pause_e_move(-retract_length, fwretract.retract_feedrate_mm_s);
#else
// If resume_position negative
if (resume_position[E_AXIS] < 0) do_pause_e_move(resume_position[E_AXIS], PAUSE_PARK_RETRACT_FEEDRATE);
@ -9029,10 +8885,10 @@ inline void gcode_M205() {
* Z[units] retract_zlift
*/
inline void gcode_M207() {
if (parser.seen('S')) retract_length = parser.value_axis_units(E_AXIS);
if (parser.seen('F')) retract_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS));
if (parser.seen('Z')) retract_zlift = parser.value_linear_units();
if (parser.seen('W')) swap_retract_length = parser.value_axis_units(E_AXIS);
if (parser.seen('S')) fwretract.retract_length = parser.value_axis_units(E_AXIS);
if (parser.seen('F')) fwretract.retract_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS));
if (parser.seen('Z')) fwretract.retract_zlift = parser.value_linear_units();
if (parser.seen('W')) fwretract.swap_retract_length = parser.value_axis_units(E_AXIS);
}
/**
@ -9044,10 +8900,10 @@ inline void gcode_M205() {
* R[units/min] swap_retract_recover_feedrate_mm_s
*/
inline void gcode_M208() {
if (parser.seen('S')) retract_recover_length = parser.value_axis_units(E_AXIS);
if (parser.seen('F')) retract_recover_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS));
if (parser.seen('R')) swap_retract_recover_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS));
if (parser.seen('W')) swap_retract_recover_length = parser.value_axis_units(E_AXIS);
if (parser.seen('S')) fwretract.retract_recover_length = parser.value_axis_units(E_AXIS);
if (parser.seen('F')) fwretract.retract_recover_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS));
if (parser.seen('R')) fwretract.swap_retract_recover_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS));
if (parser.seen('W')) fwretract.swap_retract_recover_length = parser.value_axis_units(E_AXIS);
}
/**
@ -9058,8 +8914,8 @@ inline void gcode_M205() {
inline void gcode_M209() {
if (MIN_AUTORETRACT <= MAX_AUTORETRACT) {
if (parser.seen('S')) {
autoretract_enabled = parser.value_bool();
for (uint8_t i = 0; i < EXTRUDERS; i++) retracted[i] = false;
fwretract.autoretract_enabled = parser.value_bool();
for (uint8_t i = 0; i < EXTRUDERS; i++) fwretract.retracted[i] = false;
}
}
}

View File

@ -215,6 +215,10 @@ MarlinSettings settings;
#include "ubl.h"
#endif
#if ENABLED(FWRETRACT)
#include "fwretract.h"
#endif
#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
extern void refresh_bed_level();
#endif
@ -555,24 +559,20 @@ void MarlinSettings::postprocess() {
#if DISABLED(FWRETRACT)
const bool autoretract_enabled = false;
const float retract_length = 3,
retract_feedrate_mm_s = 45,
retract_zlift = 0,
retract_recover_length = 0,
retract_recover_feedrate_mm_s = 0,
swap_retract_length = 13,
swap_retract_recover_length = 0,
swap_retract_recover_feedrate_mm_s = 8;
const float autoretract_defaults[] = { 3, 45, 0, 0, 0, 13, 0, 8 };
EEPROM_WRITE(autoretract_enabled);
EEPROM_WRITE(autoretract_defaults);
#else
EEPROM_WRITE(fwretract.autoretract_enabled);
EEPROM_WRITE(fwretract.retract_length);
EEPROM_WRITE(fwretract.retract_feedrate_mm_s);
EEPROM_WRITE(fwretract.retract_zlift);
EEPROM_WRITE(fwretract.retract_recover_length);
EEPROM_WRITE(fwretract.retract_recover_feedrate_mm_s);
EEPROM_WRITE(fwretract.swap_retract_length);
EEPROM_WRITE(fwretract.swap_retract_recover_length);
EEPROM_WRITE(fwretract.swap_retract_recover_feedrate_mm_s);
#endif
EEPROM_WRITE(autoretract_enabled);
EEPROM_WRITE(retract_length);
EEPROM_WRITE(retract_feedrate_mm_s);
EEPROM_WRITE(retract_zlift);
EEPROM_WRITE(retract_recover_length);
EEPROM_WRITE(retract_recover_feedrate_mm_s);
EEPROM_WRITE(swap_retract_length);
EEPROM_WRITE(swap_retract_recover_length);
EEPROM_WRITE(swap_retract_recover_feedrate_mm_s);
//
// Volumetric & Filament Size
@ -1070,15 +1070,15 @@ void MarlinSettings::postprocess() {
//
#if ENABLED(FWRETRACT)
EEPROM_READ(autoretract_enabled);
EEPROM_READ(retract_length);
EEPROM_READ(retract_feedrate_mm_s);
EEPROM_READ(retract_zlift);
EEPROM_READ(retract_recover_length);
EEPROM_READ(retract_recover_feedrate_mm_s);
EEPROM_READ(swap_retract_length);
EEPROM_READ(swap_retract_recover_length);
EEPROM_READ(swap_retract_recover_feedrate_mm_s);
EEPROM_READ(fwretract.autoretract_enabled);
EEPROM_READ(fwretract.retract_length);
EEPROM_READ(fwretract.retract_feedrate_mm_s);
EEPROM_READ(fwretract.retract_zlift);
EEPROM_READ(fwretract.retract_recover_length);
EEPROM_READ(fwretract.retract_recover_feedrate_mm_s);
EEPROM_READ(fwretract.swap_retract_length);
EEPROM_READ(fwretract.swap_retract_recover_length);
EEPROM_READ(fwretract.swap_retract_recover_feedrate_mm_s);
#else
EEPROM_READ(dummyb);
for (uint8_t q=8; q--;) EEPROM_READ(dummy);
@ -1549,16 +1549,8 @@ void MarlinSettings::reset() {
#endif
#if ENABLED(FWRETRACT)
autoretract_enabled = false;
retract_length = RETRACT_LENGTH;
retract_feedrate_mm_s = RETRACT_FEEDRATE;
retract_zlift = RETRACT_ZLIFT;
retract_recover_length = RETRACT_RECOVER_LENGTH;
retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE;
swap_retract_length = RETRACT_LENGTH_SWAP;
swap_retract_recover_length = RETRACT_RECOVER_LENGTH_SWAP;
swap_retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE_SWAP;
#endif // FWRETRACT
fwretract.reset();
#endif
#if DISABLED(NO_VOLUMETRICS)
@ -2052,26 +2044,26 @@ void MarlinSettings::reset() {
SERIAL_ECHOLNPGM("Retract: S<length> F<units/m> Z<lift>");
}
CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M207 S", LINEAR_UNIT(retract_length));
SERIAL_ECHOPAIR(" W", LINEAR_UNIT(swap_retract_length));
SERIAL_ECHOPAIR(" F", MMS_TO_MMM(LINEAR_UNIT(retract_feedrate_mm_s)));
SERIAL_ECHOLNPAIR(" Z", LINEAR_UNIT(retract_zlift));
SERIAL_ECHOPAIR(" M207 S", LINEAR_UNIT(fwretract.retract_length));
SERIAL_ECHOPAIR(" W", LINEAR_UNIT(fwretract.swap_retract_length));
SERIAL_ECHOPAIR(" F", MMS_TO_MMM(LINEAR_UNIT(fwretract.retract_feedrate_mm_s)));
SERIAL_ECHOLNPAIR(" Z", LINEAR_UNIT(fwretract.retract_zlift));
if (!forReplay) {
CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Recover: S<length> F<units/m>");
}
CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M208 S", LINEAR_UNIT(retract_recover_length));
SERIAL_ECHOPAIR(" W", LINEAR_UNIT(swap_retract_recover_length));
SERIAL_ECHOLNPAIR(" F", MMS_TO_MMM(LINEAR_UNIT(retract_recover_feedrate_mm_s)));
SERIAL_ECHOPAIR(" M208 S", LINEAR_UNIT(fwretract.retract_recover_length));
SERIAL_ECHOPAIR(" W", LINEAR_UNIT(fwretract.swap_retract_recover_length));
SERIAL_ECHOLNPAIR(" F", MMS_TO_MMM(LINEAR_UNIT(fwretract.retract_recover_feedrate_mm_s)));
if (!forReplay) {
CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Auto-Retract: S=0 to disable, 1 to interpret E-only moves as retract/recover");
}
CONFIG_ECHO_START;
SERIAL_ECHOLNPAIR(" M209 S", autoretract_enabled ? 1 : 0);
SERIAL_ECHOLNPAIR(" M209 S", fwretract.autoretract_enabled ? 1 : 0);
#endif // FWRETRACT
@ -2210,7 +2202,7 @@ void MarlinSettings::reset() {
#if ENABLED(ADVANCED_PAUSE_FEATURE)
if (!forReplay) {
CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Filament load & unload lengths:");
SERIAL_ECHOLNPGM("Filament load/unload lengths:");
}
CONFIG_ECHO_START;
#if EXTRUDERS == 1

196
Marlin/fwretract.cpp Normal file
View File

@ -0,0 +1,196 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* fwretract.cpp - Implement firmware-based retraction
*/
#include "MarlinConfig.h"
#if ENABLED(FWRETRACT)
#include "fwretract.h"
#include "Marlin.h"
#include "planner.h"
#include "stepper.h"
FWRetract fwretract; // Single instance - this calls the constructor
// private:
#if EXTRUDERS > 1
bool FWRetract::retracted_swap[EXTRUDERS]; // Which extruders are swap-retracted
#endif
// public:
bool FWRetract::autoretract_enabled, // M209 S - Autoretract switch
FWRetract::retracted[EXTRUDERS]; // Which extruders are currently retracted
float FWRetract::retract_length, // M207 S - G10 Retract length
FWRetract::retract_feedrate_mm_s, // M207 F - G10 Retract feedrate
FWRetract::retract_zlift, // M207 Z - G10 Retract hop size
FWRetract::retract_recover_length, // M208 S - G11 Recover length
FWRetract::retract_recover_feedrate_mm_s, // M208 F - G11 Recover feedrate
FWRetract::swap_retract_length, // M207 W - G10 Swap Retract length
FWRetract::swap_retract_recover_length, // M208 W - G11 Swap Recover length
FWRetract::swap_retract_recover_feedrate_mm_s; // M208 R - G11 Swap Recover feedrate
void FWRetract::reset() {
autoretract_enabled = false;
retract_length = RETRACT_LENGTH;
retract_feedrate_mm_s = RETRACT_FEEDRATE;
retract_zlift = RETRACT_ZLIFT;
retract_recover_length = RETRACT_RECOVER_LENGTH;
retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE;
swap_retract_length = RETRACT_LENGTH_SWAP;
swap_retract_recover_length = RETRACT_RECOVER_LENGTH_SWAP;
swap_retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE_SWAP;
for (uint8_t i = 0; i < EXTRUDERS; ++i) {
retracted[i] = false;
#if EXTRUDERS > 1
retracted_swap[i] = false;
#endif
}
}
/**
* Retract or recover according to firmware settings
*
* This function handles retract/recover moves for G10 and G11,
* plus auto-retract moves sent from G0/G1 when E-only moves are done.
*
* To simplify the logic, doubled retract/recover moves are ignored.
*
* Note: Z lift is done transparently to the planner. Aborting
* a print between G10 and G11 may corrupt the Z position.
*
* Note: Auto-retract will apply the set Z hop in addition to any Z hop
* included in the G-code. Use M207 Z0 to to prevent double hop.
*/
void FWRetract::retract(const bool retracting
#if EXTRUDERS > 1
, bool swapping /* =false */
#endif
) {
static float hop_amount = 0.0; // Total amount lifted, for use in recover
// Prevent two retracts or recovers in a row
if (retracted[active_extruder] == retracting) return;
// Prevent two swap-retract or recovers in a row
#if EXTRUDERS > 1
// Allow G10 S1 only after G10
if (swapping && retracted_swap[active_extruder] == retracting) return;
// G11 priority to recover the long retract if activated
if (!retracting) swapping = retracted_swap[active_extruder];
#else
const bool swapping = false;
#endif
/* // debugging
SERIAL_ECHOLNPAIR("retracting ", retracting);
SERIAL_ECHOLNPAIR("swapping ", swapping);
SERIAL_ECHOLNPAIR("active extruder ", active_extruder);
for (uint8_t i = 0; i < EXTRUDERS; ++i) {
SERIAL_ECHOPAIR("retracted[", i);
SERIAL_ECHOLNPAIR("] ", retracted[i]);
SERIAL_ECHOPAIR("retracted_swap[", i);
SERIAL_ECHOLNPAIR("] ", retracted_swap[i]);
}
SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]);
SERIAL_ECHOLNPAIR("hop_amount ", hop_amount);
//*/
const bool has_zhop = retract_zlift > 0.01; // Is there a hop set?
const float old_feedrate_mm_s = feedrate_mm_s;
// The current position will be the destination for E and Z moves
set_destination_from_current();
stepper.synchronize(); // Wait for buffered moves to complete
const float renormalize = 1.0 / planner.e_factor[active_extruder];
if (retracting) {
// Retract by moving from a faux E position back to the current E position
feedrate_mm_s = retract_feedrate_mm_s;
current_position[E_AXIS] += (swapping ? swap_retract_length : retract_length) * renormalize;
sync_plan_position_e();
prepare_move_to_destination();
// Is a Z hop set, and has the hop not yet been done?
// No double zlifting
// Feedrate to the max
if (has_zhop && !hop_amount) {
hop_amount += retract_zlift; // Carriage is raised for retraction hop
feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS]; // Z feedrate to max
current_position[Z_AXIS] -= retract_zlift; // Pretend current pos is lower. Next move raises Z.
SYNC_PLAN_POSITION_KINEMATIC(); // Set the planner to the new position
prepare_move_to_destination(); // Raise up to the old current pos
}
}
else {
// If a hop was done and Z hasn't changed, undo the Z hop
if (hop_amount) {
current_position[Z_AXIS] += retract_zlift; // Pretend current pos is lower. Next move raises Z.
SYNC_PLAN_POSITION_KINEMATIC(); // Set the planner to the new position
feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS]; // Z feedrate to max
prepare_move_to_destination(); // Raise up to the old current pos
hop_amount = 0.0; // Clear hop
}
// A retract multiplier has been added here to get faster swap recovery
feedrate_mm_s = swapping ? swap_retract_recover_feedrate_mm_s : retract_recover_feedrate_mm_s;
const float move_e = swapping ? swap_retract_length + swap_retract_recover_length : retract_length + retract_recover_length;
current_position[E_AXIS] -= move_e * renormalize;
sync_plan_position_e();
prepare_move_to_destination(); // Recover E
}
feedrate_mm_s = old_feedrate_mm_s; // Restore original feedrate
retracted[active_extruder] = retracting; // Active extruder now retracted / recovered
// If swap retract/recover update the retracted_swap flag too
#if EXTRUDERS > 1
if (swapping) retracted_swap[active_extruder] = retracting;
#endif
/* // debugging
SERIAL_ECHOLNPAIR("retracting ", retracting);
SERIAL_ECHOLNPAIR("swapping ", swapping);
SERIAL_ECHOLNPAIR("active_extruder ", active_extruder);
for (uint8_t i = 0; i < EXTRUDERS; ++i) {
SERIAL_ECHOPAIR("retracted[", i);
SERIAL_ECHOLNPAIR("] ", retracted[i]);
SERIAL_ECHOPAIR("retracted_swap[", i);
SERIAL_ECHOLNPAIR("] ", retracted_swap[i]);
}
SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]);
SERIAL_ECHOLNPAIR("hop_amount ", hop_amount);
//*/
}
#endif // FWRETRACT

70
Marlin/fwretract.h Normal file
View File

@ -0,0 +1,70 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* fwretract.h - Define firmware-based retraction interface
*/
#ifndef FWRETRACT_H
#define FWRETRACT_H
#include "MarlinConfig.h"
class FWRetract {
public:
static bool autoretract_enabled, // M209 S - Autoretract switch
retracted[EXTRUDERS]; // Which extruders are currently retracted
#if EXTRUDERS > 1
static bool retracted_swap[EXTRUDERS]; // Which extruders are swap-retracted
#endif
static float retract_length, // M207 S - G10 Retract length
retract_feedrate_mm_s, // M207 F - G10 Retract feedrate
retract_zlift, // M207 Z - G10 Retract hop size
retract_recover_length, // M208 S - G11 Recover length
retract_recover_feedrate_mm_s, // M208 F - G11 Recover feedrate
swap_retract_length, // M207 W - G10 Swap Retract length
swap_retract_recover_length, // M208 W - G11 Swap Recover length
swap_retract_recover_feedrate_mm_s; // M208 R - G11 Swap Recover feedrate
FWRetract() { reset(); }
static void reset();
static void refresh_autoretract() {
for (uint8_t i = 0; i < EXTRUDERS; i++) retracted[i] = false;
}
static void enable_autoretract(const bool enable) {
autoretract_enabled = enable;
refresh_autoretract();
}
static void retract(const bool retracting
#if EXTRUDERS > 1
, bool swapping = false
#endif
);
};
extern FWRetract fwretract;
#endif // FWRETRACT_H

View File

@ -56,6 +56,10 @@
#include "mesh_bed_leveling.h"
#endif
#if ENABLED(FWRETRACT)
#include "fwretract.h"
#endif
#if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(G26_MESH_VALIDATION)
bool lcd_external_control; // = false
#endif
@ -2348,7 +2352,6 @@ void kill_screen(const char* lcd_msg) {
* UBL LCD "radar" map
*/
void set_current_from_steppers_for_axis(const AxisEnum axis);
void sync_plan_position();
void _lcd_do_nothing() {}
void _lcd_hard_stop() {
@ -3748,20 +3751,20 @@ void kill_screen(const char* lcd_msg) {
void lcd_control_retract_menu() {
START_MENU();
MENU_BACK(MSG_CONTROL);
MENU_ITEM_EDIT(bool, MSG_AUTORETRACT, &autoretract_enabled);
MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT, &retract_length, 0, 100);
MENU_ITEM_EDIT(bool, MSG_AUTORETRACT, &fwretract.autoretract_enabled);
MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT, &fwretract.retract_length, 0, 100);
#if EXTRUDERS > 1
MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_SWAP, &swap_retract_length, 0, 100);
MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_SWAP, &fwretract.swap_retract_length, 0, 100);
#endif
MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACTF, &retract_feedrate_mm_s, 1, 999);
MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_ZLIFT, &retract_zlift, 0, 999);
MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_RECOVER, &retract_recover_length, -100, 100);
MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACTF, &fwretract.retract_feedrate_mm_s, 1, 999);
MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_ZLIFT, &fwretract.retract_zlift, 0, 999);
MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_RECOVER, &fwretract.retract_recover_length, -100, 100);
#if EXTRUDERS > 1
MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_RECOVER_SWAP, &swap_retract_recover_length, -100, 100);
MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_RECOVER_SWAP, &fwretract.swap_retract_recover_length, -100, 100);
#endif
MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACT_RECOVERF, &retract_recover_feedrate_mm_s, 1, 999);
MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACT_RECOVERF, &fwretract.retract_recover_feedrate_mm_s, 1, 999);
#if EXTRUDERS > 1
MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACT_RECOVER_SWAPF, &swap_retract_recover_feedrate_mm_s, 1, 999);
MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACT_RECOVER_SWAPF, &fwretract.swap_retract_recover_feedrate_mm_s, 1, 999);
#endif
END_MENU();
}