Subversion Repositories MK-Marlin

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 ron 1
/**
2
 * Marlin 3D Printer Firmware
3
 * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
 *
5
 * Based on Sprinter and grbl.
6
 * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 *
21
 */
22
 
23
/**
24
 * fwretract.cpp - Implement firmware-based retraction
25
 */
26
 
27
#include "MarlinConfig.h"
28
 
29
#if ENABLED(FWRETRACT)
30
 
31
#include "fwretract.h"
32
#include "Marlin.h"
33
#include "planner.h"
34
#include "stepper.h"
35
 
36
FWRetract fwretract; // Single instance - this calls the constructor
37
 
38
// private:
39
 
40
#if EXTRUDERS > 1
41
  bool FWRetract::retracted_swap[EXTRUDERS];         // Which extruders are swap-retracted
42
#endif
43
 
44
// public:
45
 
46
bool FWRetract::autoretract_enabled,                 // M209 S - Autoretract switch
47
     FWRetract::retracted[EXTRUDERS];                // Which extruders are currently retracted
48
float FWRetract::retract_length,                     // M207 S - G10 Retract length
49
      FWRetract::retract_feedrate_mm_s,              // M207 F - G10 Retract feedrate
50
      FWRetract::retract_zlift,                      // M207 Z - G10 Retract hop size
51
      FWRetract::retract_recover_length,             // M208 S - G11 Recover length
52
      FWRetract::retract_recover_feedrate_mm_s,      // M208 F - G11 Recover feedrate
53
      FWRetract::swap_retract_length,                // M207 W - G10 Swap Retract length
54
      FWRetract::swap_retract_recover_length,        // M208 W - G11 Swap Recover length
55
      FWRetract::swap_retract_recover_feedrate_mm_s, // M208 R - G11 Swap Recover feedrate
56
      FWRetract::hop_amount;
57
 
58
void FWRetract::reset() {
59
  autoretract_enabled = false;
60
  retract_length = RETRACT_LENGTH;
61
  retract_feedrate_mm_s = RETRACT_FEEDRATE;
62
  retract_zlift = RETRACT_ZLIFT;
63
  retract_recover_length = RETRACT_RECOVER_LENGTH;
64
  retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE;
65
  swap_retract_length = RETRACT_LENGTH_SWAP;
66
  swap_retract_recover_length = RETRACT_RECOVER_LENGTH_SWAP;
67
  swap_retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE_SWAP;
68
  hop_amount = 0.0;
69
 
70
  for (uint8_t i = 0; i < EXTRUDERS; ++i) {
71
    retracted[i] = false;
72
    #if EXTRUDERS > 1
73
      retracted_swap[i] = false;
74
    #endif
75
  }
76
}
77
 
78
/**
79
 * Retract or recover according to firmware settings
80
 *
81
 * This function handles retract/recover moves for G10 and G11,
82
 * plus auto-retract moves sent from G0/G1 when E-only moves are done.
83
 *
84
 * To simplify the logic, doubled retract/recover moves are ignored.
85
 *
86
 * Note: Z lift is done transparently to the planner. Aborting
87
 *       a print between G10 and G11 may corrupt the Z position.
88
 *
89
 * Note: Auto-retract will apply the set Z hop in addition to any Z hop
90
 *       included in the G-code. Use M207 Z0 to to prevent double hop.
91
 */
92
void FWRetract::retract(const bool retracting
93
  #if EXTRUDERS > 1
94
    , bool swapping /* =false */
95
  #endif
96
) {
97
 
98
  static float hop_amount = 0.0;  // Total amount lifted, for use in recover
99
 
100
  // Prevent two retracts or recovers in a row
101
  if (retracted[active_extruder] == retracting) return;
102
 
103
  // Prevent two swap-retract or recovers in a row
104
  #if EXTRUDERS > 1
105
    // Allow G10 S1 only after G10
106
    if (swapping && retracted_swap[active_extruder] == retracting) return;
107
    // G11 priority to recover the long retract if activated
108
    if (!retracting) swapping = retracted_swap[active_extruder];
109
  #else
110
    constexpr bool swapping = false;
111
  #endif
112
 
113
  /* // debugging
114
    SERIAL_ECHOLNPAIR("retracting ", retracting);
115
    SERIAL_ECHOLNPAIR("swapping ", swapping);
116
    SERIAL_ECHOLNPAIR("active extruder ", active_extruder);
117
    for (uint8_t i = 0; i < EXTRUDERS; ++i) {
118
      SERIAL_ECHOPAIR("retracted[", i);
119
      SERIAL_ECHOLNPAIR("] ", retracted[i]);
120
      #if EXTRUDERS > 1
121
        SERIAL_ECHOPAIR("retracted_swap[", i);
122
        SERIAL_ECHOLNPAIR("] ", retracted_swap[i]);
123
      #endif
124
    }
125
    SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]);
126
    SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_CART]);
127
    SERIAL_ECHOLNPAIR("hop_amount ", hop_amount);
128
  //*/
129
 
130
  const float old_feedrate_mm_s = feedrate_mm_s,
131
              renormalize = RECIPROCAL(planner.e_factor[active_extruder]),
132
              base_retract = swapping ? swap_retract_length : retract_length,
133
              old_z = current_position[Z_AXIS],
134
              old_e = current_position[E_CART];
135
 
136
  // The current position will be the destination for E and Z moves
137
  set_destination_from_current();
138
 
139
  if (retracting) {
140
    // Retract by moving from a faux E position back to the current E position
141
    feedrate_mm_s = retract_feedrate_mm_s;
142
    destination[E_CART] -= base_retract * renormalize;
143
    prepare_move_to_destination();                        // set_current_to_destination
144
 
145
    // Is a Z hop set, and has the hop not yet been done?
146
    if (retract_zlift > 0.01 && !hop_amount) {            // Apply hop only once
147
      hop_amount += retract_zlift;                        // Add to the hop total (again, only once)
148
      destination[Z_AXIS] += retract_zlift;               // Raise Z by the zlift (M207 Z) amount
149
      feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS];  // Maximum Z feedrate
150
      prepare_move_to_destination();                      // Raise up, set_current_to_destination
151
    }
152
  }
153
  else {
154
    // If a hop was done and Z hasn't changed, undo the Z hop
155
    if (hop_amount) {
156
      current_position[Z_AXIS] += hop_amount;             // Restore the actual Z position
157
      SYNC_PLAN_POSITION_KINEMATIC();                     // Unspoof the position planner
158
      feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS];  // Z feedrate to max
159
      prepare_move_to_destination();                      // Lower Z, set_current_to_destination
160
      hop_amount = 0.0;                                   // Clear the hop amount
161
    }
162
 
163
    destination[E_CART] += (base_retract + (swapping ? swap_retract_recover_length : retract_recover_length)) * renormalize;
164
    feedrate_mm_s = swapping ? swap_retract_recover_feedrate_mm_s : retract_recover_feedrate_mm_s;
165
    prepare_move_to_destination();                        // Recover E, set_current_to_destination
166
  }
167
 
168
  feedrate_mm_s = old_feedrate_mm_s;                      // Restore original feedrate
169
  current_position[Z_AXIS] = old_z;                       // Restore Z and E positions
170
  current_position[E_CART] = old_e;
171
  SYNC_PLAN_POSITION_KINEMATIC();                         // As if the move never took place
172
 
173
  retracted[active_extruder] = retracting;                // Active extruder now retracted / recovered
174
 
175
  // If swap retract/recover update the retracted_swap flag too
176
  #if EXTRUDERS > 1
177
    if (swapping) retracted_swap[active_extruder] = retracting;
178
  #endif
179
 
180
  /* // debugging
181
    SERIAL_ECHOLNPAIR("retracting ", retracting);
182
    SERIAL_ECHOLNPAIR("swapping ", swapping);
183
    SERIAL_ECHOLNPAIR("active_extruder ", active_extruder);
184
    for (uint8_t i = 0; i < EXTRUDERS; ++i) {
185
      SERIAL_ECHOPAIR("retracted[", i);
186
      SERIAL_ECHOLNPAIR("] ", retracted[i]);
187
      #if EXTRUDERS > 1
188
        SERIAL_ECHOPAIR("retracted_swap[", i);
189
        SERIAL_ECHOLNPAIR("] ", retracted_swap[i]);
190
      #endif
191
    }
192
    SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]);
193
    SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_CART]);
194
    SERIAL_ECHOLNPAIR("hop_amount ", hop_amount);
195
  //*/
196
 
197
}
198
 
199
#endif // FWRETRACT