Prusa MINI Firmware overview
motion.cpp File Reference
#include "motion.h"
#include "endstops.h"
#include "stepper.h"
#include "planner.h"
#include "temperature.h"
#include "../gcode/gcode.h"
#include "../inc/MarlinConfig.h"
#include "../feature/bedlevel/bedlevel.h"
#include "../core/debug_out.h"

Macros

#define DEBUG_OUT   ENABLED(DEBUG_LEVELING_FEATURE)
 
#define XYZ_CONSTS(T, NAME, OPT)   const PROGMEM XYZval<T> NAME##_P = { X_##OPT, Y_##OPT, Z_##OPT }
 
#define HOMED_FLAGS   axis_homed
 
#define _CAN_HOME(A)   (axis == _AXIS(A) && ((A##_MIN_PIN > -1 && A##_HOME_DIR < 0) || (A##_MAX_PIN > -1 && A##_HOME_DIR > 0)))
 
#define CAN_HOME_X   _CAN_HOME(X)
 
#define CAN_HOME_Y   _CAN_HOME(Y)
 
#define CAN_HOME_Z   _CAN_HOME(Z)
 

Functions

 XYZ_CONSTS (float, base_min_pos, MIN_POS)
 
 XYZ_CONSTS (float, base_max_pos, MAX_POS)
 
 XYZ_CONSTS (float, base_home_pos, HOME_POS)
 
 XYZ_CONSTS (float, max_length, MAX_LENGTH)
 
 XYZ_CONSTS (float, home_bump_mm, HOME_BUMP_MM)
 
 XYZ_CONSTS (signed char, home_dir, HOME_DIR)
 
void report_current_position ()
 
void sync_plan_position ()
 
void sync_plan_position_e ()
 
void get_cartesian_from_steppers ()
 
void set_current_from_steppers_for_axis (const AxisEnum axis)
 
void line_to_current_position (const feedRate_t &fr_mm_s)
 
void _internal_move_to_destination (const feedRate_t &fr_mm_s)
 
void do_blocking_move_to (const float rx, const float ry, const float rz, const feedRate_t &fr_mm_s)
 
void do_blocking_move_to (const xy_pos_t &raw, const feedRate_t &fr_mm_s)
 
void do_blocking_move_to (const xyz_pos_t &raw, const feedRate_t &fr_mm_s)
 
void do_blocking_move_to (const xyze_pos_t &raw, const feedRate_t &fr_mm_s)
 
void do_blocking_move_to_x (const float &rx, const feedRate_t &fr_mm_s)
 
void do_blocking_move_to_y (const float &ry, const feedRate_t &fr_mm_s)
 
void do_blocking_move_to_z (const float &rz, const feedRate_t &fr_mm_s)
 
void do_blocking_move_to_xy (const float &rx, const float &ry, const feedRate_t &fr_mm_s)
 
void do_blocking_move_to_xy (const xy_pos_t &raw, const feedRate_t &fr_mm_s)
 
void do_blocking_move_to_xy_z (const xy_pos_t &raw, const float &z, const feedRate_t &fr_mm_s)
 
void remember_feedrate_and_scaling ()
 
void remember_feedrate_scaling_off ()
 
void restore_feedrate_and_scaling ()
 
void update_software_endstops (const AxisEnum axis)
 
void apply_motion_limits (xyz_pos_t &target)
 
bool prepare_move_to_destination_cartesian ()
 
void prepare_move_to_destination ()
 
uint8_t axes_need_homing (uint8_t axis_bits)
 
bool axis_unhomed_error (uint8_t axis_bits)
 
feedRate_t get_homing_bump_feedrate (const AxisEnum axis)
 
void do_homing_move (const AxisEnum axis, const float distance, const feedRate_t fr_mm_s=0.0)
 
void set_axis_is_at_home (const AxisEnum axis)
 
void set_axis_is_not_at_home (const AxisEnum axis)
 
void homeaxis (const AxisEnum axis)
 

Variables

uint8_t axis_homed
 
uint8_t axis_known_position
 
bool relative_mode
 
xyze_pos_t current_position = { X_HOME_POS, Y_HOME_POS, Z_HOME_POS }
 
xyze_pos_t destination
 
feedRate_t feedrate_mm_s = MMM_TO_MMS(1500)
 
int16_t feedrate_percentage = 100
 
const feedRate_t homing_feedrate_mm_s[XYZPROGMEM
 
xyz_pos_t cartes
 
float xy_probe_feedrate_mm_s = MMM_TO_MMS(XY_PROBE_SPEED)
 
static float saved_feedrate_mm_s
 
static int16_t saved_feedrate_percentage
 
bool soft_endstops_enabled = true
 
axis_limits_t soft_endstop
 
bool extruder_duplication_enabled
 
bool mirrored_duplication_mode
 

Macro Definition Documentation

◆ DEBUG_OUT

#define DEBUG_OUT   ENABLED(DEBUG_LEVELING_FEATURE)

Marlin 3D Printer Firmware Copyright (c) 2019 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/. motion.cpp

◆ XYZ_CONSTS

#define XYZ_CONSTS (   T,
  NAME,
  OPT 
)    const PROGMEM XYZval<T> NAME##_P = { X_##OPT, Y_##OPT, Z_##OPT }

◆ HOMED_FLAGS

#define HOMED_FLAGS   axis_homed

◆ _CAN_HOME

#define _CAN_HOME (   A)    (axis == _AXIS(A) && ((A##_MIN_PIN > -1 && A##_HOME_DIR < 0) || (A##_MAX_PIN > -1 && A##_HOME_DIR > 0)))

◆ CAN_HOME_X

#define CAN_HOME_X   _CAN_HOME(X)

◆ CAN_HOME_Y

#define CAN_HOME_Y   _CAN_HOME(Y)

◆ CAN_HOME_Z

#define CAN_HOME_Z   _CAN_HOME(Z)

Function Documentation

◆ XYZ_CONSTS() [1/6]

XYZ_CONSTS ( float  ,
base_min_pos  ,
MIN_POS   
)

◆ XYZ_CONSTS() [2/6]

XYZ_CONSTS ( float  ,
base_max_pos  ,
MAX_POS   
)

◆ XYZ_CONSTS() [3/6]

XYZ_CONSTS ( float  ,
base_home_pos  ,
HOME_POS   
)

◆ XYZ_CONSTS() [4/6]

XYZ_CONSTS ( float  ,
max_length  ,
MAX_LENGTH   
)

◆ XYZ_CONSTS() [5/6]

XYZ_CONSTS ( float  ,
home_bump_mm  ,
HOME_BUMP_MM   
)

◆ XYZ_CONSTS() [6/6]

XYZ_CONSTS ( signed char  ,
home_dir  ,
HOME_DIR   
)

◆ report_current_position()

void report_current_position ( )

Output the current position to serial

199  {
200  const xyz_pos_t lpos = current_position.asLogical();
201  SERIAL_ECHOPAIR("X:", lpos.x, " Y:", lpos.y, " Z:", lpos.z, " E:", current_position.e);
202 
204 
205  #if IS_SCARA
207  #endif
208 }
Here is the call graph for this function:

◆ sync_plan_position()

void sync_plan_position ( )

sync_plan_position

Set the planner/stepper positions directly from current_position with no kinematic translation. Used for homing axes and cartesian/core syncing.

216  {
217  if (DEBUGGING(LEVELING)) DEBUG_POS("sync_plan_position", current_position);
219 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sync_plan_position_e()

void sync_plan_position_e ( )
Here is the call graph for this function:

◆ get_cartesian_from_steppers()

void get_cartesian_from_steppers ( )

Get the stepper positions in the cartes[] array. Forward kinematics are applied for DELTA and SCARA.

The result is in the current coordinate space with leveling applied. The coordinates need to be run through unapply_leveling to obtain the "ideal" coordinates suitable for current_position, etc.

232  {
233  #if ENABLED(DELTA)
238  );
239  #else
240  #if IS_SCARA
242  planner.get_axis_position_degrees(A_AXIS),
243  planner.get_axis_position_degrees(B_AXIS)
244  );
245  #else
247  #endif
249  #endif
250 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_current_from_steppers_for_axis()

void set_current_from_steppers_for_axis ( const AxisEnum  axis)

Set the current_position for an axis based on the stepper positions, removing any leveling that may have been applied.

To prevent small shifts in axis position always call sync_plan_position after updating axes with this.

To keep hosts in sync, always call report_current_position after updating the current_position.

263  {
265 
266  #if HAS_POSITION_MODIFIERS
269  #if HAS_LEVELING
270  , true
271  #endif
272  );
273  xyze_pos_t &cartes = pos;
274  #endif
275  if (axis == ALL_AXES)
277  else
278  current_position[axis] = cartes[axis];
279 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ line_to_current_position()

void line_to_current_position ( const feedRate_t fr_mm_s)

Move the planner to the current position from wherever it last moved (or from wherever it has been told it is located).

285  {
287 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _internal_move_to_destination()

void _internal_move_to_destination ( const feedRate_t fr_mm_s)
315  {
316  const feedRate_t old_feedrate = feedrate_mm_s;
317  if (fr_mm_s) feedrate_mm_s = fr_mm_s;
318 
319  const uint16_t old_pct = feedrate_percentage;
320  feedrate_percentage = 100;
321 
322  #if EXTRUDERS
323  const float old_fac = planner.e_factor[active_extruder];
324  planner.e_factor[active_extruder] = 1.0f;
325  #endif
326 
327  #if IS_KINEMATIC
328  if (is_fast)
329  prepare_fast_move_to_destination();
330  else
331  #endif
333 
334  feedrate_mm_s = old_feedrate;
335  feedrate_percentage = old_pct;
336  #if EXTRUDERS
337  planner.e_factor[active_extruder] = old_fac;
338  #endif
339 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_blocking_move_to() [1/4]

void do_blocking_move_to ( const float  rx,
const float  ry,
const float  rz,
const feedRate_t fr_mm_s 
)

Plan a move to (X, Y, Z) and set the current_position

344  {
345  if (DEBUGGING(LEVELING)) DEBUG_XYZ(">>> do_blocking_move_to", rx, ry, rz);
346 
347  const feedRate_t z_feedrate = fr_mm_s ?: homing_feedrate(Z_AXIS),
348  xy_feedrate = fr_mm_s ?: feedRate_t(XY_PROBE_FEEDRATE_MM_S);
349 
350  #if ENABLED(DELTA)
351 
352  if (!position_is_reachable(rx, ry)) return;
353 
354  REMEMBER(fr, feedrate_mm_s, xy_feedrate);
355 
356  destination = current_position; // sync destination at the start
357 
358  if (DEBUGGING(LEVELING)) DEBUG_POS("destination = current_position", destination);
359 
360  // when in the danger zone
362  if (rz > delta_clip_start_height) { // staying in the danger zone
363  destination.set(rx, ry, rz); // move directly (uninterpolated)
364  prepare_internal_fast_move_to_destination(); // set current_position from destination
365  if (DEBUGGING(LEVELING)) DEBUG_POS("danger zone move", current_position);
366  return;
367  }
369  prepare_internal_fast_move_to_destination(); // set current_position from destination
370  if (DEBUGGING(LEVELING)) DEBUG_POS("zone border move", current_position);
371  }
372 
373  if (rz > current_position.z) { // raising?
374  destination.z = rz;
375  prepare_internal_fast_move_to_destination(z_feedrate); // set current_position from destination
376  if (DEBUGGING(LEVELING)) DEBUG_POS("z raise move", current_position);
377  }
378 
379  destination.set(rx, ry);
380  prepare_internal_move_to_destination(); // set current_position from destination
381  if (DEBUGGING(LEVELING)) DEBUG_POS("xy move", current_position);
382 
383  if (rz < current_position.z) { // lowering?
384  destination.z = rz;
385  prepare_internal_fast_move_to_destination(z_feedrate); // set current_position from destination
386  if (DEBUGGING(LEVELING)) DEBUG_POS("z lower move", current_position);
387  }
388 
389  #elif IS_SCARA
390 
391  if (!position_is_reachable(rx, ry)) return;
392 
394 
395  // If Z needs to raise, do it before moving XY
396  if (destination.z < rz) {
397  destination.z = rz;
398  prepare_internal_fast_move_to_destination(z_feedrate);
399  }
400 
401  destination.set(rx, ry);
402  prepare_internal_fast_move_to_destination(xy_feedrate);
403 
404  // If Z needs to lower, do it after moving XY
405  if (destination.z > rz) {
406  destination.z = rz;
407  prepare_internal_fast_move_to_destination(z_feedrate);
408  }
409 
410  #else
411 
412  // If Z needs to raise, do it before moving XY
413  if (current_position.z < rz) {
414  current_position.z = rz;
415  line_to_current_position(z_feedrate);
416  }
417 
418  current_position.set(rx, ry);
419  line_to_current_position(xy_feedrate);
420 
421  // If Z needs to lower, do it after moving XY
422  if (current_position.z > rz) {
423  current_position.z = rz;
424  line_to_current_position(z_feedrate);
425  }
426 
427  #endif
428 
429  if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< do_blocking_move_to");
430 
432 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_blocking_move_to() [2/4]

void do_blocking_move_to ( const xy_pos_t raw,
const feedRate_t fr_mm_s 
)
434  {
435  do_blocking_move_to(raw.x, raw.y, current_position.z, fr_mm_s);
436 }
Here is the call graph for this function:

◆ do_blocking_move_to() [3/4]

void do_blocking_move_to ( const xyz_pos_t raw,
const feedRate_t fr_mm_s 
)
437  {
438  do_blocking_move_to(raw.x, raw.y, raw.z, fr_mm_s);
439 }
Here is the call graph for this function:

◆ do_blocking_move_to() [4/4]

void do_blocking_move_to ( const xyze_pos_t raw,
const feedRate_t fr_mm_s 
)
440  {
441  do_blocking_move_to(raw.x, raw.y, raw.z, fr_mm_s);
442 }
Here is the call graph for this function:

◆ do_blocking_move_to_x()

void do_blocking_move_to_x ( const float &  rx,
const feedRate_t fr_mm_s 
)
444  {
446 }
Here is the call graph for this function:

◆ do_blocking_move_to_y()

void do_blocking_move_to_y ( const float &  ry,
const feedRate_t fr_mm_s 
)
447  {
449 }
Here is the call graph for this function:

◆ do_blocking_move_to_z()

void do_blocking_move_to_z ( const float &  rz,
const feedRate_t fr_mm_s 
)
450  {
452 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_blocking_move_to_xy() [1/2]

void do_blocking_move_to_xy ( const float &  rx,
const float &  ry,
const feedRate_t fr_mm_s 
)
454  {
455  do_blocking_move_to(rx, ry, current_position.z, fr_mm_s);
456 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_blocking_move_to_xy() [2/2]

void do_blocking_move_to_xy ( const xy_pos_t raw,
const feedRate_t fr_mm_s 
)
457  {
458  do_blocking_move_to_xy(raw.x, raw.y, fr_mm_s);
459 }
Here is the call graph for this function:

◆ do_blocking_move_to_xy_z()

void do_blocking_move_to_xy_z ( const xy_pos_t raw,
const float &  z,
const feedRate_t fr_mm_s 
)
461  {
462  do_blocking_move_to(raw.x, raw.y, z, fr_mm_s);
463 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ remember_feedrate_and_scaling()

void remember_feedrate_and_scaling ( )
Here is the caller graph for this function:

◆ remember_feedrate_scaling_off()

void remember_feedrate_scaling_off ( )
475  {
477  feedrate_percentage = 100;
478 }
Here is the call graph for this function:

◆ restore_feedrate_and_scaling()

void restore_feedrate_and_scaling ( )

◆ update_software_endstops()

void update_software_endstops ( const AxisEnum  axis)

Software endstops can be used to monitor the open end of an axis that has a hardware endstop on the other end. Or they can prevent axes from moving past endstops and grinding.

To keep doing their job as the coordinate system changes, the software endstop positions must be refreshed to remain at the same positions relative to the machine.

507  {
508 
509  #if ENABLED(DUAL_X_CARRIAGE)
510 
511  if (axis == X_AXIS) {
512 
513  // In Dual X mode hotend_offset[X] is T1's home position
514  const float dual_max_x = _MAX(hotend_offset[1].x, X2_MAX_POS);
515 
516  if (new_tool_index != 0) {
517  // T1 can move from X2_MIN_POS to X2_MAX_POS or X2 home position (whichever is larger)
518  soft_endstop.min.x = X2_MIN_POS;
519  soft_endstop.max.x = dual_max_x;
520  }
521  else if (dxc_is_duplicating()) {
522  // In Duplication Mode, T0 can move as far left as X1_MIN_POS
523  // but not so far to the right that T1 would move past the end
524  soft_endstop.min.x = X1_MIN_POS;
525  soft_endstop.max.x = _MIN(X1_MAX_POS, dual_max_x - duplicate_extruder_x_offset);
526  }
527  else {
528  // In other modes, T0 can move from X1_MIN_POS to X1_MAX_POS
529  soft_endstop.min.x = X1_MIN_POS;
530  soft_endstop.max.x = X1_MAX_POS;
531  }
532 
533  }
534 
535  #elif ENABLED(DELTA)
536 
537  soft_endstop.min[axis] = base_min_pos(axis);
538  soft_endstop.max[axis] = (axis == Z_AXIS ? delta_height
539  #if HAS_BED_PROBE
540  - probe_offset.z
541  #endif
542  : base_max_pos(axis));
543 
544  switch (axis) {
545  case X_AXIS:
546  case Y_AXIS:
547  // Get a minimum radius for clamping
549  delta_max_radius_2 = sq(delta_max_radius);
550  break;
551  case Z_AXIS:
553  default: break;
554  }
555 
556  #elif HAS_HOTEND_OFFSET
557 
558  // Software endstops are relative to the tool 0 workspace, so
559  // the movement limits must be shifted by the tool offset to
560  // retain the same physical limit when other tools are selected.
561  if (old_tool_index != new_tool_index) {
562  const float offs = hotend_offset[new_tool_index][axis] - hotend_offset[old_tool_index][axis];
563  soft_endstop.min[axis] += offs;
564  soft_endstop.max[axis] += offs;
565  }
566  else {
567  const float offs = hotend_offset[active_extruder][axis];
568  soft_endstop.min[axis] = base_min_pos(axis) + offs;
569  soft_endstop.max[axis] = base_max_pos(axis) + offs;
570  }
571 
572  #else
573 
574  soft_endstop.min[axis] = base_min_pos(axis);
575  soft_endstop.max[axis] = base_max_pos(axis);
576 
577  #endif
578 
579  if (DEBUGGING(LEVELING))
580  SERIAL_ECHOLNPAIR("Axis ", axis_codes[axis], " min:", soft_endstop.min[axis], " max:", soft_endstop.max[axis]);
581 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ apply_motion_limits()

void apply_motion_limits ( xyz_pos_t target)

Constrain the given coordinates to the software endstops.

For DELTA/SCARA the XY constraint is based on the smallest radius within the set software endstops.

589  {
590 
591  if (!soft_endstops_enabled || !all_axes_homed()) return;
592 
593  #if IS_KINEMATIC
594 
595  #if HAS_HOTEND_OFFSET && ENABLED(DELTA)
596  // The effector center position will be the target minus the hotend offset.
597  const xy_pos_t offs = hotend_offset[active_extruder];
598  #else
599  // SCARA needs to consider the angle of the arm through the entire move, so for now use no tool offset.
600  constexpr xy_pos_t offs{0};
601  #endif
602 
603  const float dist_2 = HYPOT2(target.x - offs.x, target.y - offs.y);
604  if (dist_2 > delta_max_radius_2)
605  target *= delta_max_radius / SQRT(dist_2); // 200 / 300 = 0.66
606 
607  #else
608 
609  #if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_X)
610  NOLESS(target.x, soft_endstop.min.x);
611  #endif
612  #if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_X)
613  NOMORE(target.x, soft_endstop.max.x);
614  #endif
615  #if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_Y)
616  NOLESS(target.y, soft_endstop.min.y);
617  #endif
618  #if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_Y)
619  NOMORE(target.y, soft_endstop.max.y);
620  #endif
621 
622  #endif
623 
624  #if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_Z)
625  NOLESS(target.z, soft_endstop.min.z);
626  #endif
627  #if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_Z)
628  NOMORE(target.z, soft_endstop.max.z);
629  #endif
630  }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ prepare_move_to_destination_cartesian()

bool prepare_move_to_destination_cartesian ( )

Prepare a linear move in a Cartesian setup.

When a mesh-based leveling system is active, moves are segmented according to the configuration of the leveling system.

Return true if 'current_position' was set to 'destination'

For MBL and ABL-BILINEAR only segment moves when X or Y are involved. Otherwise fall through to do a direct single move.

841  {
842  const float scaled_fr_mm_s = MMS_SCALED(feedrate_mm_s);
843  #if HAS_MESH
845  #if ENABLED(AUTO_BED_LEVELING_UBL)
846  ubl.line_to_destination_cartesian(scaled_fr_mm_s, active_extruder); // UBL's motion routine needs to know about
847  return true; // all moves, including Z-only moves.
848  #elif ENABLED(SEGMENT_LEVELED_MOVES)
849  segmented_line_to_destination(scaled_fr_mm_s);
850  return false; // caller will update current_position
851  #else
852  /**
853  * For MBL and ABL-BILINEAR only segment moves when X or Y are involved.
854  * Otherwise fall through to do a direct single move.
855  */
857  #if ENABLED(MESH_BED_LEVELING)
858  mbl.line_to_destination(scaled_fr_mm_s);
859  #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
860  bilinear_line_to_destination(scaled_fr_mm_s);
861  #endif
862  return true;
863  }
864  #endif
865  }
866  #endif // HAS_MESH
867 
869  return false; // caller will update current_position
870  }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ prepare_move_to_destination()

void prepare_move_to_destination ( )

Prepare a single move and get ready for the next one

This may result in several calls to planner.buffer_line to do smaller moves for DELTA, SCARA, mesh moves, etc.

Make sure current_position.e and destination.e are good before calling or cold/lengthy extrusion may get missed.

Before exit, current_position is set to destination.

984  {
986 
987  #if EITHER(PREVENT_COLD_EXTRUSION, PREVENT_LENGTHY_EXTRUDE)
988 
989  if (!DEBUGGING(DRYRUN)) {
990  if (destination.e != current_position.e) {
991  #if ENABLED(PREVENT_COLD_EXTRUSION)
993  current_position.e = destination.e; // Behave as if the move really took place, but ignore E part
995  }
996  #endif // PREVENT_COLD_EXTRUSION
997  #if ENABLED(PREVENT_LENGTHY_EXTRUDE)
998  const float e_delta = ABS(destination.e - current_position.e) * planner.e_factor[active_extruder];
999  if (e_delta > (EXTRUDE_MAXLENGTH)) {
1000  #if ENABLED(MIXING_EXTRUDER)
1001  bool ignore_e = false;
1002  float collector[MIXING_STEPPERS];
1003  mixer.refresh_collector(1.0, mixer.get_current_vtool(), collector);
1005  if (e_delta * collector[e] > (EXTRUDE_MAXLENGTH)) { ignore_e = true; break; }
1006  #else
1007  constexpr bool ignore_e = true;
1008  #endif
1009  if (ignore_e) {
1010  current_position.e = destination.e; // Behave as if the move really took place, but ignore E part
1012  }
1013  }
1014  #endif // PREVENT_LENGTHY_EXTRUDE
1015  }
1016  }
1017 
1018  #endif // PREVENT_COLD_EXTRUSION || PREVENT_LENGTHY_EXTRUDE
1019 
1020  #if ENABLED(DUAL_X_CARRIAGE)
1021  if (dual_x_carriage_unpark()) return;
1022  #endif
1023 
1024  if (
1025  #if UBL_SEGMENTED
1026  #if IS_KINEMATIC // UBL using Kinematic / Cartesian cases as a workaround for now.
1027  ubl.line_to_destination_segmented(MMS_SCALED(feedrate_mm_s))
1028  #else
1030  #endif
1031  #elif IS_KINEMATIC
1032  line_to_destination_kinematic()
1033  #else
1035  #endif
1036  ) return;
1037 
1039 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ axes_need_homing()

uint8_t axes_need_homing ( uint8_t  axis_bits)
1041  {
1042  #if ENABLED(HOME_AFTER_DEACTIVATE)
1043  #define HOMED_FLAGS axis_known_position
1044  #else
1045  #define HOMED_FLAGS axis_homed
1046  #endif
1047  // Clear test bits that are homed
1048  if (TEST(axis_bits, X_AXIS) && TEST(HOMED_FLAGS, X_AXIS)) CBI(axis_bits, X_AXIS);
1049  if (TEST(axis_bits, Y_AXIS) && TEST(HOMED_FLAGS, Y_AXIS)) CBI(axis_bits, Y_AXIS);
1050  if (TEST(axis_bits, Z_AXIS) && TEST(HOMED_FLAGS, Z_AXIS)) CBI(axis_bits, Z_AXIS);
1051  return axis_bits;
1052 }
Here is the caller graph for this function:

◆ axis_unhomed_error()

bool axis_unhomed_error ( uint8_t  axis_bits)
1054  {
1055  if ((axis_bits = axes_need_homing(axis_bits))) {
1056  PGM_P home_first = GET_TEXT(MSG_HOME_FIRST);
1057  char msg[strlen_P(home_first)+1];
1058  sprintf_P(msg, home_first,
1059  TEST(axis_bits, X_AXIS) ? "X" : "",
1060  TEST(axis_bits, Y_AXIS) ? "Y" : "",
1061  TEST(axis_bits, Z_AXIS) ? "Z" : ""
1062  );
1064  SERIAL_ECHOLN(msg);
1065  #if HAS_DISPLAY
1066  ui.set_status(msg);
1067  #endif
1068  return true;
1069  }
1070  return false;
1071 }
Here is the call graph for this function:

◆ get_homing_bump_feedrate()

feedRate_t get_homing_bump_feedrate ( const AxisEnum  axis)

Homing bump feedrate (mm/s)

1076  {
1077  #if HOMING_Z_WITH_PROBE
1078  if (axis == Z_AXIS) return MMM_TO_MMS(Z_PROBE_SPEED_SLOW);
1079  #endif
1080  static const uint8_t homing_bump_divisor[] PROGMEM = HOMING_BUMP_DIVISOR;
1081  uint8_t hbd = pgm_read_byte(&homing_bump_divisor[axis]);
1082  if (hbd < 1) {
1083  hbd = 10;
1084  SERIAL_ECHO_MSG("Warning: Homing Bump Divisor < 1");
1085  }
1086  return homing_feedrate(axis) / float(hbd);
1087 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_homing_move()

void do_homing_move ( const AxisEnum  axis,
const float  distance,
const feedRate_t  fr_mm_s = 0.0 
)

Home an individual linear axis

1232  {
1233 
1234  if (DEBUGGING(LEVELING)) {
1235  DEBUG_ECHOPAIR(">>> do_homing_move(", axis_codes[axis], ", ", distance, ", ");
1236  if (fr_mm_s)
1237  DEBUG_ECHO(fr_mm_s);
1238  else
1239  DEBUG_ECHOPAIR("[", homing_feedrate(axis), "]");
1240  DEBUG_ECHOLNPGM(")");
1241  }
1242 
1243  #if HOMING_Z_WITH_PROBE && HAS_HEATED_BED && ENABLED(WAIT_FOR_BED_HEATER)
1244  // Wait for bed to heat back up between probing points
1245  if (axis == Z_AXIS && distance < 0 && thermalManager.isHeatingBed()) {
1246  serialprintPGM(msg_wait_for_bed_heating);
1247  LCD_MESSAGEPGM(MSG_BED_HEATING);
1248  thermalManager.wait_for_bed();
1249  ui.reset_status();
1250  }
1251  #endif
1252 
1253  // Only do some things when moving towards an endstop
1254  const int8_t axis_home_dir =
1255  #if ENABLED(DUAL_X_CARRIAGE)
1256  (axis == X_AXIS) ? x_home_dir(active_extruder) :
1257  #endif
1258  home_dir(axis);
1259  const bool is_home_dir = (axis_home_dir > 0) == (distance > 0);
1260 
1261  #if ENABLED(SENSORLESS_HOMING)
1262  sensorless_t stealth_states;
1263  #endif
1264 
1265  if (is_home_dir) {
1266 
1267  #if HOMING_Z_WITH_PROBE && QUIET_PROBING
1268  if (axis == Z_AXIS) probing_pause(true);
1269  #endif
1270 
1271  // Disable stealthChop if used. Enable diag1 pin on driver.
1272  #if ENABLED(SENSORLESS_HOMING)
1273  stealth_states = start_sensorless_homing_per_axis(axis);
1274  #endif
1275  }
1276 
1277  const feedRate_t real_fr_mm_s = fr_mm_s ?: homing_feedrate(axis);
1278 
1279  if ((axis == X_AXIS) || (axis == Y_AXIS))
1280  {
1282  target[axis] = 0;
1284  float dist = (distance > 0)?-1.92F:1.92F;
1285  target[axis] = dist;
1286 #if IS_KINEMATIC && DISABLED(CLASSIC_JERK)
1287  const xyze_float_t delta_mm_cart{0};
1288 #endif
1289  // Set delta/cartesian axes directly
1290  planner.buffer_segment(target
1291 #if IS_KINEMATIC && DISABLED(CLASSIC_JERK)
1292  , delta_mm_cart
1293 #endif
1294  , real_fr_mm_s / 4, active_extruder
1295  );
1296  planner.synchronize();
1297  }
1298 
1299  #if IS_SCARA
1300  // Tell the planner the axis is at 0
1301  current_position[axis] = 0;
1303  current_position[axis] = distance;
1304  line_to_current_position(real_fr_mm_s);
1305  #else
1307  target[axis] = 0;
1309  target[axis] = distance;
1310 
1311  #if IS_KINEMATIC && DISABLED(CLASSIC_JERK)
1312  const xyze_float_t delta_mm_cart{0};
1313  #endif
1314 
1315  // Set delta/cartesian axes directly
1316  planner.buffer_segment(target
1317  #if IS_KINEMATIC && DISABLED(CLASSIC_JERK)
1318  , delta_mm_cart
1319  #endif
1320  , real_fr_mm_s, active_extruder
1321  );
1322  #endif
1323 
1324  planner.synchronize();
1325 
1326  if (is_home_dir) {
1327 
1328  #if HOMING_Z_WITH_PROBE && QUIET_PROBING
1329  if (axis == Z_AXIS) probing_pause(false);
1330  #endif
1331 
1333 
1334  // Re-enable stealthChop if used. Disable diag1 pin on driver.
1335  #if ENABLED(SENSORLESS_HOMING)
1336  end_sensorless_homing_per_axis(axis, stealth_states);
1337  #endif
1338  }
1339 
1340  if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("<<< do_homing_move(", axis_codes[axis], ")");
1341 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_axis_is_at_home()

void set_axis_is_at_home ( const AxisEnum  axis)

Set an axis' current position to its home position (after homing).

For Core and Cartesian robots this applies one-to-one when an individual axis has been homed.

DELTA should wait until all homing is done before setting the XYZ current_position to home, because homing is a single operation. In the case where the axis positions are already known and previously homed, DELTA could home to X or Y individually by moving either one to the center. However, homing Z always homes XY and Z.

SCARA should wait until all XY homing is done before setting the XY current_position to home, because neither X nor Y is at home until both are at home. Z can however be homed individually.

Callers must sync the planner position after calling this!

Z Probe Z Homing? Account for the probe's Z offset.

1361  {
1362  if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR(">>> set_axis_is_at_home(", axis_codes[axis], ")");
1363 
1364  SBI(axis_known_position, axis);
1365  SBI(axis_homed, axis);
1366 
1367  #if ENABLED(DUAL_X_CARRIAGE)
1368  if (axis == X_AXIS && (active_extruder == 1 || dual_x_carriage_mode == DXC_DUPLICATION_MODE)) {
1369  current_position.x = x_home_pos(active_extruder);
1370  return;
1371  }
1372  #endif
1373 
1374  #if ENABLED(MORGAN_SCARA)
1376  #elif ENABLED(DELTA)
1377  current_position[axis] = (axis == Z_AXIS ? delta_height
1378  #if HAS_BED_PROBE
1379  - probe_offset.z
1380  #endif
1381  : base_home_pos(axis));
1382  #else
1383  current_position[axis] = base_home_pos(axis);
1384  #endif
1385 
1386  /**
1387  * Z Probe Z Homing? Account for the probe's Z offset.
1388  */
1389  #if HAS_BED_PROBE && Z_HOME_DIR < 0
1390  if (axis == Z_AXIS) {
1391  #if HOMING_Z_WITH_PROBE
1392 
1394 
1395  if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("*** Z HOMED WITH PROBE (Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) ***\n> probe_offset.z = ", probe_offset.z);
1396 
1397  #else
1398 
1399  if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("*** Z HOMED TO ENDSTOP ***");
1400 
1401  #endif
1402  }
1403  #endif
1404 
1405  #if ENABLED(I2C_POSITION_ENCODERS)
1406  I2CPEM.homed(axis);
1407  #endif
1408 
1409  #if ENABLED(BABYSTEP_DISPLAY_TOTAL)
1410  babystep.reset_total(axis);
1411  #endif
1412 
1413  if (DEBUGGING(LEVELING)) {
1414  #if HAS_HOME_OFFSET
1415  DEBUG_ECHOLNPAIR("> home_offset[", axis_codes[axis], "] = ", home_offset[axis]);
1416  #endif
1418  DEBUG_ECHOLNPAIR("<<< set_axis_is_at_home(", axis_codes[axis], ")");
1419  }
1420 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_axis_is_not_at_home()

void set_axis_is_not_at_home ( const AxisEnum  axis)

Set an axis' to be unhomed.

1425  {
1426  if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR(">>> set_axis_is_not_at_home(", axis_codes[axis], ")");
1427 
1428  CBI(axis_known_position, axis);
1429  CBI(axis_homed, axis);
1430 
1431  if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("<<< set_axis_is_not_at_home(", axis_codes[axis], ")");
1432 
1433  #if ENABLED(I2C_POSITION_ENCODERS)
1434  I2CPEM.unhomed(axis);
1435  #endif
1436 }
Here is the call graph for this function:

◆ homeaxis()

void homeaxis ( const AxisEnum  axis)

Home an individual "raw axis" to its endstop. This applies to XYZ on Cartesian and Core robots, and to the individual ABC steppers on DELTA and SCARA.

At the end of the procedure the axis is marked as homed and the current position of that axis is updated. Kinematic robots should wait till all axes are homed before updating the current position.

1449  {
1450 
1451  #if IS_SCARA
1452  // Only Z homing (with probe) is permitted
1453  if (axis != Z_AXIS) { BUZZ(100, 880); return; }
1454  #else
1455  #define _CAN_HOME(A) \
1456  (axis == _AXIS(A) && ((A##_MIN_PIN > -1 && A##_HOME_DIR < 0) || (A##_MAX_PIN > -1 && A##_HOME_DIR > 0)))
1457  #if X_SPI_SENSORLESS
1458  #define CAN_HOME_X true
1459  #else
1460  #define CAN_HOME_X _CAN_HOME(X)
1461  #endif
1462  #if Y_SPI_SENSORLESS
1463  #define CAN_HOME_Y true
1464  #else
1465  #define CAN_HOME_Y _CAN_HOME(Y)
1466  #endif
1467  #if Z_SPI_SENSORLESS
1468  #define CAN_HOME_Z true
1469  #else
1470  #define CAN_HOME_Z _CAN_HOME(Z)
1471  #endif
1472  if (!CAN_HOME_X && !CAN_HOME_Y && !CAN_HOME_Z) return;
1473  #endif
1474 
1475  if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR(">>> homeaxis(", axis_codes[axis], ")");
1476 
1477  const int axis_home_dir = (
1478  #if ENABLED(DUAL_X_CARRIAGE)
1479  axis == X_AXIS ? x_home_dir(active_extruder) :
1480  #endif
1481  home_dir(axis)
1482  );
1483 
1484  // Homing Z towards the bed? Deploy the Z probe or endstop.
1485  #if HOMING_Z_WITH_PROBE
1486  if (axis == Z_AXIS && DEPLOY_PROBE()) return;
1487  #endif
1488 
1489  // Set flags for X, Y, Z motor locking
1490  #if HAS_EXTRA_ENDSTOPS
1491  switch (axis) {
1492  #if ENABLED(X_DUAL_ENDSTOPS)
1493  case X_AXIS:
1494  #endif
1495  #if ENABLED(Y_DUAL_ENDSTOPS)
1496  case Y_AXIS:
1497  #endif
1498  #if Z_MULTI_ENDSTOPS
1499  case Z_AXIS:
1500  #endif
1502  default: break;
1503  }
1504  #endif
1505 
1506  // Fast move towards endstop until triggered
1507  if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Home 1 Fast:");
1508 
1509  #if HOMING_Z_WITH_PROBE && ENABLED(BLTOUCH)
1510  if (axis == Z_AXIS && bltouch.deploy()) return; // The initial DEPLOY
1511  #endif
1512 
1513  do_homing_move(axis, 1.5f * max_length(
1514  #if ENABLED(DELTA)
1515  Z_AXIS
1516  #else
1517  axis
1518  #endif
1519  ) * axis_home_dir
1520  );
1521 
1522  #if HOMING_Z_WITH_PROBE && ENABLED(BLTOUCH) && DISABLED(BLTOUCH_HS_MODE)
1523  if (axis == Z_AXIS) bltouch.stow(); // Intermediate STOW (in LOW SPEED MODE)
1524  #endif
1525 
1526  // When homing Z with probe respect probe clearance
1527  const float bump = axis_home_dir * (
1528  #if HOMING_Z_WITH_PROBE
1530  #endif
1531  home_bump_mm(axis)
1532  );
1533 
1534  // If a second homing move is configured...
1535  if (bump) {
1536  // Move away from the endstop by the axis HOME_BUMP_MM
1537  if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Move Away:");
1538  do_homing_move(axis, -bump
1540  , MMM_TO_MMS(axis == Z_AXIS ? Z_PROBE_SPEED_FAST : 0)
1541  #endif
1542  );
1543 
1544  // Slow move towards endstop until triggered
1545  if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Home 2 Slow:");
1546 
1547  #if HOMING_Z_WITH_PROBE && ENABLED(BLTOUCH) && DISABLED(BLTOUCH_HS_MODE)
1548  if (axis == Z_AXIS && bltouch.deploy()) return; // Intermediate DEPLOY (in LOW SPEED MODE)
1549  #endif
1550 
1551  do_homing_move(axis, 2 * bump, get_homing_bump_feedrate(axis));
1552 
1553  #if HOMING_Z_WITH_PROBE && ENABLED(BLTOUCH)
1554  if (axis == Z_AXIS) bltouch.stow(); // The final STOW
1555  #endif
1556  }
1557 
1558  #if HAS_EXTRA_ENDSTOPS
1559  const bool pos_dir = axis_home_dir > 0;
1560  #if ENABLED(X_DUAL_ENDSTOPS)
1561  if (axis == X_AXIS) {
1562  const float adj = ABS(endstops.x2_endstop_adj);
1563  if (adj) {
1564  if (pos_dir ? (endstops.x2_endstop_adj > 0) : (endstops.x2_endstop_adj < 0)) stepper.set_x_lock(true); else stepper.set_x2_lock(true);
1565  do_homing_move(axis, pos_dir ? -adj : adj);
1566  stepper.set_x_lock(false);
1567  stepper.set_x2_lock(false);
1568  }
1569  }
1570  #endif
1571  #if ENABLED(Y_DUAL_ENDSTOPS)
1572  if (axis == Y_AXIS) {
1573  const float adj = ABS(endstops.y2_endstop_adj);
1574  if (adj) {
1575  if (pos_dir ? (endstops.y2_endstop_adj > 0) : (endstops.y2_endstop_adj < 0)) stepper.set_y_lock(true); else stepper.set_y2_lock(true);
1576  do_homing_move(axis, pos_dir ? -adj : adj);
1577  stepper.set_y_lock(false);
1578  stepper.set_y2_lock(false);
1579  }
1580  }
1581  #endif
1582  #if ENABLED(Z_DUAL_ENDSTOPS)
1583  if (axis == Z_AXIS) {
1584  const float adj = ABS(endstops.z2_endstop_adj);
1585  if (adj) {
1586  if (pos_dir ? (endstops.z2_endstop_adj > 0) : (endstops.z2_endstop_adj < 0)) stepper.set_z_lock(true); else stepper.set_z2_lock(true);
1587  do_homing_move(axis, pos_dir ? -adj : adj);
1588  stepper.set_z_lock(false);
1589  stepper.set_z2_lock(false);
1590  }
1591  }
1592  #endif
1593  #if ENABLED(Z_TRIPLE_ENDSTOPS)
1594  if (axis == Z_AXIS) {
1595  // we push the function pointers for the stepper lock function into an array
1596  void (*lock[3]) (bool)= {&stepper.set_z_lock, &stepper.set_z2_lock, &stepper.set_z3_lock};
1597  float adj[3] = {0, endstops.z2_endstop_adj, endstops.z3_endstop_adj};
1598 
1599  void (*tempLock) (bool);
1600  float tempAdj;
1601 
1602  // manual bubble sort by adjust value
1603  if (adj[1] < adj[0]) {
1604  tempLock = lock[0], tempAdj = adj[0];
1605  lock[0] = lock[1], adj[0] = adj[1];
1606  lock[1] = tempLock, adj[1] = tempAdj;
1607  }
1608  if (adj[2] < adj[1]) {
1609  tempLock = lock[1], tempAdj = adj[1];
1610  lock[1] = lock[2], adj[1] = adj[2];
1611  lock[2] = tempLock, adj[2] = tempAdj;
1612  }
1613  if (adj[1] < adj[0]) {
1614  tempLock = lock[0], tempAdj = adj[0];
1615  lock[0] = lock[1], adj[0] = adj[1];
1616  lock[1] = tempLock, adj[1] = tempAdj;
1617  }
1618 
1619  if (pos_dir) {
1620  // normalize adj to smallest value and do the first move
1621  (*lock[0])(true);
1622  do_homing_move(axis, adj[1] - adj[0]);
1623  // lock the second stepper for the final correction
1624  (*lock[1])(true);
1625  do_homing_move(axis, adj[2] - adj[1]);
1626  }
1627  else {
1628  (*lock[2])(true);
1629  do_homing_move(axis, adj[1] - adj[2]);
1630  (*lock[1])(true);
1631  do_homing_move(axis, adj[0] - adj[1]);
1632  }
1633 
1634  stepper.set_z_lock(false);
1635  stepper.set_z2_lock(false);
1636  stepper.set_z3_lock(false);
1637  }
1638  #endif
1639 
1640  // Reset flags for X, Y, Z motor locking
1641  switch (axis) {
1642  #if ENABLED(X_DUAL_ENDSTOPS)
1643  case X_AXIS:
1644  #endif
1645  #if ENABLED(Y_DUAL_ENDSTOPS)
1646  case Y_AXIS:
1647  #endif
1648  #if Z_MULTI_ENDSTOPS
1649  case Z_AXIS:
1650  #endif
1652  default: break;
1653  }
1654  #endif
1655 
1656  #if IS_SCARA
1657 
1658  set_axis_is_at_home(axis);
1660 
1661  #elif ENABLED(DELTA)
1662 
1663  // Delta has already moved all three towers up in G28
1664  // so here it re-homes each tower in turn.
1665  // Delta homing treats the axes as normal linear axes.
1666 
1667  // retrace by the amount specified in delta_endstop_adj + additional dist in order to have minimum steps
1668  if (delta_endstop_adj[axis] * Z_HOME_DIR <= 0) {
1669  if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("delta_endstop_adj:");
1671  }
1672 
1673  #else // CARTESIAN / CORE
1674 
1675  set_axis_is_at_home(axis);
1677 
1678  destination[axis] = current_position[axis];
1679 
1680  if (DEBUGGING(LEVELING)) DEBUG_POS("> AFTER set_axis_is_at_home", current_position);
1681 
1682  #endif
1683 
1684  // Put away the Z probe
1685  #if HOMING_Z_WITH_PROBE
1686  if (axis == Z_AXIS && STOW_PROBE()) return;
1687  #endif
1688 
1689  #ifdef HOMING_BACKOFF_MM
1690  constexpr xyz_float_t endstop_backoff = HOMING_BACKOFF_MM;
1691  const float backoff_mm = endstop_backoff[
1692  #if ENABLED(DELTA)
1693  Z_AXIS
1694  #else
1695  axis
1696  #endif
1697  ];
1698  if (backoff_mm) {
1699  current_position[axis] -= ABS(backoff_mm) * axis_home_dir;
1702  (axis == Z_AXIS) ? MMM_TO_MMS(Z_PROBE_SPEED_FAST) :
1703  #endif
1704  homing_feedrate(axis)
1705  );
1706  }
1707  #endif
1708 
1709  // Clear retracted status if homing the Z axis
1710  #if ENABLED(FWRETRACT)
1711  if (axis == Z_AXIS) fwretract.current_hop = 0.0;
1712  #endif
1713 
1714  if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("<<< homeaxis(", axis_codes[axis], ")");
1715 
1716 } // homeaxis()
Here is the call graph for this function:

Variable Documentation

◆ axis_homed

uint8_t axis_homed

axis_homed Flags that each linear axis was homed. XYZ on cartesian, ABC on delta, ABZ on SCARA.

axis_known_position Flags that the position is known in each linear axis. Set when homed. Cleared whenever a stepper powers off, potentially losing its position.

◆ axis_known_position

uint8_t axis_known_position

◆ relative_mode

bool relative_mode

◆ current_position

xyze_pos_t current_position = { X_HOME_POS, Y_HOME_POS, Z_HOME_POS }

Cartesian Current Position Used to track the native machine position as moves are queued. Used by 'line_to_current_position' to do a move after changing it. Used by 'sync_plan_position' to update 'planner.position'.

◆ destination

xyze_pos_t destination

Cartesian Destination The destination for a move, filled in by G-code movement commands, and expected by functions like 'prepare_move_to_destination'. G-codes can set destination using 'get_destination_from_command'

◆ feedrate_mm_s

feedRate_t feedrate_mm_s = MMM_TO_MMS(1500)

◆ feedrate_percentage

int16_t feedrate_percentage = 100

Feedrate scaling

◆ PROGMEM

◆ cartes

xyz_pos_t cartes

◆ xy_probe_feedrate_mm_s

float xy_probe_feedrate_mm_s = MMM_TO_MMS(XY_PROBE_SPEED)

The workspace can be offset by some commands, or these offsets may be omitted to save on computation.

◆ saved_feedrate_mm_s

float saved_feedrate_mm_s
static

◆ saved_feedrate_percentage

int16_t saved_feedrate_percentage
static

◆ soft_endstops_enabled

bool soft_endstops_enabled = true

◆ soft_endstop

axis_limits_t soft_endstop
Initial value:

◆ extruder_duplication_enabled

bool extruder_duplication_enabled

Duplication mode

◆ mirrored_duplication_mode

bool mirrored_duplication_mode
delta_clip_start_height
float delta_clip_start_height
XYZval::z
T z
Definition: types.h:286
Planner::set_machine_position_mm
static void set_machine_position_mm(const float &a, const float &b, const float &c, const float &e)
Definition: planner.cpp:2721
GET_TEXT
#define GET_TEXT(MSG)
Definition: multi_language.h:72
Temperature::tooColdToExtrude
static FORCE_INLINE bool tooColdToExtrude(const uint8_t)
Definition: temperature.h:314
bilinear_line_to_destination
void bilinear_line_to_destination(const feedRate_t &scaled_fr_mm_s, uint16_t x_splits=0xFFFF, uint16_t y_splits=0xFFFF)
Y_MIN_POS
#define Y_MIN_POS
Definition: Configuration_A3ides_2209_MINI.h:985
NOLESS
#define NOLESS(v, n)
Definition: macros.h:127
HOMING_Z_WITH_PROBE
#define HOMING_Z_WITH_PROBE
Definition: Conditionals_LCD.h:505
XYZEval
Definition: types.h:101
Stepper::report_positions
static void report_positions()
Definition: stepper.cpp:2276
sq
#define sq(x)
Definition: wiring_constants.h:83
XYZEval::z
T z
Definition: types.h:383
Planner::synchronize
static void synchronize()
Definition: planner.cpp:1556
mbl
mesh_bed_leveling mbl
axis_limits_t::max
xyz_pos_t max
Definition: motion.h:139
mixer
Mixer mixer
XYZval::x
T x
Definition: types.h:286
DEPLOY_PROBE
#define DEPLOY_PROBE()
Definition: probe.h:60
axis_limits_t::min
xyz_pos_t min
Definition: motion.h:139
MSG_ERR_COLD_EXTRUDE_STOP
#define MSG_ERR_COLD_EXTRUDE_STOP
Definition: language.h:242
probe_offset
constexpr xyz_pos_t probe_offset
Definition: probe.h:58
Z_PROBE_SPEED_FAST
#define Z_PROBE_SPEED_FAST
Definition: Configuration_A3ides_2209_MINI.h:868
Z_MIN_POS
#define Z_MIN_POS
Definition: Configuration_A3ides_2209_MINI.h:986
X_AXIS
Definition: types.h:37
DEBUG_ECHOLNPGM
#define DEBUG_ECHOLNPGM(...)
Definition: debug_out.h:79
XYZEval::asLogical
FI XYZEval< float > asLogical() const
Definition: types.h:410
DEBUG_XYZ
#define DEBUG_XYZ(...)
Definition: debug_out.h:88
stepper
Stepper stepper
Definition: stepper.cpp:82
Planner::buffer_segment
static bool buffer_segment(const float &a, const float &b, const float &c, const float &e, const feedRate_t &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0)
Definition: planner.cpp:2568
_MAX
#define _MAX(V...)
Definition: macros.h:346
Planner::get_axis_position_mm
static float get_axis_position_mm(const AxisEnum axis)
Definition: planner.cpp:1526
axis_homed
uint8_t axis_homed
Definition: motion.cpp:91
Planner::leveling_active
static bool leveling_active
Definition: planner.h:276
SERIAL_ECHOPAIR
#define SERIAL_ECHOPAIR(V...)
Definition: serial.h:114
MIN_STEPS_PER_SEGMENT
#define MIN_STEPS_PER_SEGMENT
Definition: Configuration_A3ides_2209_MINI_adv.h:1108
do_blocking_move_to_xy_z
void do_blocking_move_to_xy_z(const xy_pos_t &raw, const float &z, const feedRate_t &fr_mm_s)
Definition: motion.cpp:461
UBL_SEGMENTED
#define UBL_SEGMENTED
Definition: Conditionals_post.h:1403
do_blocking_move_to_xy
void do_blocking_move_to_xy(const float &rx, const float &ry, const feedRate_t &fr_mm_s)
Definition: motion.cpp:454
HOMED_FLAGS
#define HOMED_FLAGS
Z_HOME_DIR
#define Z_HOME_DIR
Definition: Configuration_A3ides_2209_MINI.h:975
C_AXIS
Definition: types.h:39
Endstops::validate_homing_move
static FORCE_INLINE void validate_homing_move()
Definition: endstops.h:144
Stepper::set_z2_lock
static FORCE_INLINE void set_z2_lock(const bool state)
Definition: stepper.h:422
PGM_P
#define PGM_P
Definition: pgmspace.h:30
XYZEval::e
T e
Definition: types.h:383
set_axis_is_at_home
void set_axis_is_at_home(const AxisEnum axis)
Definition: motion.cpp:1361
I2CPEM
I2CPositionEncodersMgr I2CPEM
HYPOT2
#define HYPOT2(x, y)
Definition: macros.h:100
babystep
Babystep babystep
_MIN
#define _MIN(V...)
Definition: macros.h:333
saved_feedrate_mm_s
static float saved_feedrate_mm_s
Definition: motion.cpp:469
unified_bed_leveling::line_to_destination_cartesian
static void line_to_destination_cartesian(const feedRate_t &scaled_fr_mm_s, const uint8_t e)
forward_kinematics_SCARA
void forward_kinematics_SCARA(const float &a, const float &b)
xy_pos_t
xy_float_t xy_pos_t
Definition: types.h:159
DEBUG_ECHOLNPAIR
#define DEBUG_ECHOLNPAIR(...)
Definition: debug_out.h:82
IS_KINEMATIC
#define IS_KINEMATIC
Definition: Conditionals_LCD.h:545
SERIAL_ECHO_START
#define SERIAL_ECHO_START()
Definition: serial.h:179
SERIAL_ECHOLN
#define SERIAL_ECHOLN(x)
Definition: serial.h:72
I2CPositionEncodersMgr::unhomed
static void unhomed(const AxisEnum axis)
Definition: I2CPositionEncoder.h:230
remember_feedrate_and_scaling
void remember_feedrate_and_scaling()
Definition: motion.cpp:471
delta_height
float delta_height
feedRate_t
float feedRate_t
Definition: types.h:80
sprintf_P
#define sprintf_P(s,...)
Definition: pgmspace.h:72
XYZval::set
FI void set(const T px)
Definition: types.h:290
soft_endstops_enabled
bool soft_endstops_enabled
Definition: motion.cpp:486
strlen_P
#define strlen_P(s)
Definition: pgmspace.h:61
delta_endstop_adj
abc_float_t delta_endstop_adj
F
#define F(str)
Definition: UHS_macros.h:164
Planner::unapply_modifiers
static FORCE_INLINE void unapply_modifiers(xyze_pos_t &pos, bool leveling=false)
Definition: planner.h:520
BLTouch::deploy
static FORCE_INLINE bool deploy()
Definition: bltouch.h:72
prepare_move_to_destination_cartesian
bool prepare_move_to_destination_cartesian()
Definition: motion.cpp:841
X_MIN_POS
#define X_MIN_POS
Definition: Configuration_A3ides_2209_MINI.h:984
NOMORE
#define NOMORE(v, n)
Definition: macros.h:133
Z_MAX_POS
#define Z_MAX_POS
Definition: Configuration_A3ides_2209_MINI.h:989
ABS
#define ABS(a)
Definition: macros.h:266
Z_PROBE_SPEED_SLOW
#define Z_PROBE_SPEED_SLOW
Definition: Configuration_A3ides_2209_MINI.h:871
pgm_read_byte
#define pgm_read_byte(addr)
Definition: pgmspace.h:95
bltouch
BLTouch bltouch
prepare_internal_move_to_destination
void prepare_internal_move_to_destination(const feedRate_t &fr_mm_s=0.0f)
Definition: motion.h:186
Y_MAX_POS
#define Y_MAX_POS
Definition: Configuration_A3ides_2209_MINI.h:988
SERIAL_ECHO_MSG
#define SERIAL_ECHO_MSG(S)
Definition: serial.h:183
current_position
xyze_pos_t current_position
Definition: motion.cpp:102
feedrate_percentage
int16_t feedrate_percentage
Definition: motion.cpp:139
position_is_reachable
bool position_is_reachable(const float &rx, const float &ry)
Definition: motion.h:325
Z_CLEARANCE_BETWEEN_PROBES
#define Z_CLEARANCE_BETWEEN_PROBES
Definition: Configuration_A3ides_2209_MINI.h:893
Planner::leveling_active_at_z
static FORCE_INLINE bool leveling_active_at_z(const float &)
Definition: planner.h:447
HAS_LEVELING
#define HAS_LEVELING
Definition: Conditionals_post.h:1408
PROGMEM
const feedRate_t homing_feedrate_mm_s[XYZ] PROGMEM
Definition: motion.cpp:142
line_to_current_position
void line_to_current_position(const feedRate_t &fr_mm_s)
Definition: motion.cpp:285
do_blocking_move_to
void do_blocking_move_to(const float rx, const float ry, const float rz, const feedRate_t &fr_mm_s)
Definition: motion.cpp:344
cartes
xyz_pos_t cartes
Definition: motion.cpp:152
scara_set_axis_is_at_home
void scara_set_axis_is_at_home(const AxisEnum axis)
sync_plan_position
void sync_plan_position()
Definition: motion.cpp:216
REMEMBER
#define REMEMBER(N, X, V...)
Definition: utility.h:76
DISABLED
#define DISABLED(V...)
Definition: macros.h:178
void
void
Definition: png.h:1083
delta_safe_distance_from_top
float delta_safe_distance_from_top()
Mixer::refresh_collector
static void refresh_collector(const float proportion=1.0, const uint8_t t=selected_vtool, float(&c)[MIXING_STEPPERS]=collector)
XYZEval::x
T x
Definition: types.h:383
ALL_AXES
Definition: types.h:48
XY_PROBE_FEEDRATE_MM_S
#define XY_PROBE_FEEDRATE_MM_S
Definition: motion.h:77
Planner::buffer_line
static bool buffer_line(const float &rx, const float &ry, const float &rz, const float &e, const feedRate_t &fr_mm_s, const uint8_t extruder, const float millimeters=0.0)
Definition: planner.cpp:2663
feedrate_mm_s
feedRate_t feedrate_mm_s
Definition: motion.cpp:138
CAN_HOME_X
#define CAN_HOME_X
SERIAL_ECHOLNPAIR
#define SERIAL_ECHOLNPAIR(V...)
Definition: serial.h:144
get_homing_bump_feedrate
feedRate_t get_homing_bump_feedrate(const AxisEnum axis)
Definition: motion.cpp:1076
XYval
Definition: types.h:99
scara_report_positions
void scara_report_positions()
Z_HOME_BUMP_MM
#define Z_HOME_BUMP_MM
Definition: Configuration_A3ides_2209_MINI_adv.h:457
Stepper::set_separate_multi_axis
static FORCE_INLINE void set_separate_multi_axis(const bool state)
Definition: stepper.h:410
axis_known_position
uint8_t axis_known_position
Definition: motion.cpp:91
XYZEval::set
FI void set(const T px)
Definition: types.h:391
SQRT
#define SQRT(x)
Definition: macros.h:281
XYval::x
T x
Definition: types.h:185
MIXER_STEPPER_LOOP
#define MIXER_STEPPER_LOOP(VAR)
Definition: mixing.h:68
DEBUG_POS
#define DEBUG_POS(...)
Definition: debug_out.h:87
do_homing_move
void do_homing_move(const AxisEnum axis, const float distance, const feedRate_t fr_mm_s=0.0)
Definition: motion.cpp:1232
Endstops::z2_endstop_adj
static float z2_endstop_adj
Definition: endstops.h:51
get_cartesian_from_steppers
void get_cartesian_from_steppers()
Definition: motion.cpp:232
uint8_t
const uint8_t[]
Definition: 404_html.c:3
ui
MarlinUI ui
DEBUG_ECHO
#define DEBUG_ECHO(...)
Definition: debug_out.h:75
XYZval::y
T y
Definition: types.h:286
Planner::steps_to_mm
static float steps_to_mm[XYZE_N]
Definition: planner.h:254
destination
xyze_pos_t destination
Definition: motion.cpp:110
homing_feedrate
FORCE_INLINE feedRate_t homing_feedrate(const AxisEnum a)
Definition: motion.h:93
X_MAX_POS
#define X_MAX_POS
Definition: Configuration_A3ides_2209_MINI.h:987
Y_AXIS
Definition: types.h:38
CBI
#define CBI(A, B)
Definition: macros.h:89
hotend_offset
constexpr xyz_pos_t hotend_offset[1]
Definition: motion.h:136
Planner::set_e_position_mm
static void set_e_position_mm(const float &e)
Definition: planner.cpp:2764
ubl
unified_bed_leveling ubl
MSG_ERR_LONG_EXTRUDE_STOP
#define MSG_ERR_LONG_EXTRUDE_STOP
Definition: language.h:243
prepare_move_to_destination
void prepare_move_to_destination()
Definition: motion.cpp:984
Z_AXIS
Definition: types.h:39
apply_motion_limits
void apply_motion_limits(xyz_pos_t &target)
Definition: motion.cpp:589
DEBUGGING
#define DEBUGGING(F)
Definition: serial.h:47
A_AXIS
Definition: types.h:37
axes_need_homing
uint8_t axes_need_homing(uint8_t axis_bits)
Definition: motion.cpp:1041
STOW_PROBE
#define STOW_PROBE()
Definition: probe.h:61
DEBUG_ECHOPAIR
#define DEBUG_ECHOPAIR(...)
Definition: debug_out.h:80
TEST
#define TEST(n, b)
Definition: macros.h:81
MMM_TO_MMS
#define MMM_TO_MMS(MM_M)
Definition: types.h:83
I2CPositionEncodersMgr::homed
static void homed(const AxisEnum axis)
Definition: I2CPositionEncoder.h:225
XYval::y
T y
Definition: types.h:185
HOMING_FEEDRATE_XY
#define HOMING_FEEDRATE_XY
Definition: Configuration_A3ides_2209_MINI.h:1268
HOMING_BUMP_DIVISOR
#define HOMING_BUMP_DIVISOR
Definition: Configuration_A3ides_2209_MINI_adv.h:458
forward_kinematics_DELTA
void forward_kinematics_DELTA(const float &z1, const float &z2, const float &z3)
XYZval< float >
E_AXIS
Definition: types.h:40
CAN_HOME_Z
#define CAN_HOME_Z
serialprintPGM
void serialprintPGM(PGM_P str)
Definition: serial.cpp:35
B_AXIS
Definition: types.h:38
SBI
#define SBI(A, B)
Definition: macros.h:85
axis_codes
const xyze_char_t axis_codes
Definition: types.h:486
Planner::set_position_mm
static void set_position_mm(const float &rx, const float &ry, const float &rz, const float &e)
Definition: planner.cpp:2741
MMS_SCALED
#define MMS_SCALED(V)
Definition: types.h:85
soft_endstop
axis_limits_t soft_endstop
Definition: motion.cpp:489
thermalManager
Temperature thermalManager
Definition: temperature.cpp:89
endstops
Endstops endstops
Definition: endstops.cpp:51
CAN_HOME_Y
#define CAN_HOME_Y
Mixer::get_current_vtool
static FORCE_INLINE uint8_t get_current_vtool()
Definition: mixing.h:111
BUZZ
#define BUZZ(d, f)
Definition: buzzer.h:126
mesh_bed_leveling::line_to_destination
static void line_to_destination(const feedRate_t &scaled_fr_mm_s, uint8_t x_splits=0xFF, uint8_t y_splits=0xFF)
active_extruder
constexpr uint8_t active_extruder
Definition: motion.h:107
Stepper::set_z_lock
static FORCE_INLINE void set_z_lock(const bool state)
Definition: stepper.h:421
ENABLED
#define ENABLED(V...)
Definition: macros.h:177
planner
Planner planner
Definition: planner.cpp:111
all_axes_homed
FORCE_INLINE bool all_axes_homed()
Definition: motion.h:44
XYZEval::y
T y
Definition: types.h:383
saved_feedrate_percentage
static int16_t saved_feedrate_percentage
Definition: motion.cpp:470
BLTouch::stow
static FORCE_INLINE bool stow()
Definition: bltouch.h:73
EXTRUDE_MAXLENGTH
#define EXTRUDE_MAXLENGTH
Definition: Configuration_A3ides_2209_MINI.h:524