🚸 Enable G92.9 with rotational axes (#26174)
- Supporting axes that can rotate forever.
This commit is contained in:
parent
d609bb4671
commit
c8d51c2723
|
@ -42,7 +42,7 @@
|
||||||
* G92 : Modify Workspace Offsets so the reported position shows the given X [Y [Z [A [B [C [U [V [W ]]]]]]]] [E].
|
* G92 : Modify Workspace Offsets so the reported position shows the given X [Y [Z [A [B [C [U [V [W ]]]]]]]] [E].
|
||||||
* G92.1 : Zero XYZ Workspace Offsets (so the reported position = the native position).
|
* G92.1 : Zero XYZ Workspace Offsets (so the reported position = the native position).
|
||||||
*
|
*
|
||||||
* With POWER_LOSS_RECOVERY:
|
* With POWER_LOSS_RECOVERY or with AXISn_ROTATES:
|
||||||
* G92.9 : Set NATIVE Current Position to the given X [Y [Z [A [B [C [U [V [W ]]]]]]]] [E].
|
* G92.9 : Set NATIVE Current Position to the given X [Y [Z [A [B [C [U [V [W ]]]]]]]] [E].
|
||||||
*/
|
*/
|
||||||
void GcodeSuite::G92() {
|
void GcodeSuite::G92() {
|
||||||
|
@ -67,7 +67,7 @@ void GcodeSuite::G92() {
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(POWER_LOSS_RECOVERY)
|
#if ANY(POWER_LOSS_RECOVERY, HAS_ROTATIONAL_AXES)
|
||||||
case 9: // G92.9 - Set Current Position directly (like Marlin 1.0)
|
case 9: // G92.9 - Set Current Position directly (like Marlin 1.0)
|
||||||
LOOP_LOGICAL_AXES(i) {
|
LOOP_LOGICAL_AXES(i) {
|
||||||
if (parser.seenval(AXIS_CHAR(i))) {
|
if (parser.seenval(AXIS_CHAR(i))) {
|
||||||
|
|
|
@ -3279,7 +3279,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Add commands that need sub-codes to this list
|
// Add commands that need sub-codes to this list
|
||||||
#if ANY(G38_PROBE_TARGET, CNC_COORDINATE_SYSTEMS, POWER_LOSS_RECOVERY)
|
#if ANY(G38_PROBE_TARGET, CNC_COORDINATE_SYSTEMS, POWER_LOSS_RECOVERY, HAS_ROTATIONAL_AXES)
|
||||||
#define USE_GCODE_SUBCODES 1
|
#define USE_GCODE_SUBCODES 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "../inc/MarlinConfig.h"
|
#include "../inc/MarlinConfig.h"
|
||||||
|
|
||||||
#include "../MarlinCore.h" // for printingIsPaused
|
#include "../MarlinCore.h" // for printingIsPaused
|
||||||
|
#include "../gcode/parser.h" // for axis_is_rotational, using_inch_units
|
||||||
|
|
||||||
#if LED_POWEROFF_TIMEOUT > 0 || ALL(HAS_WIRED_LCD, PRINTER_EVENT_LEDS) || (HAS_BACKLIGHT_TIMEOUT && defined(NEOPIXEL_BKGD_INDEX_FIRST))
|
#if LED_POWEROFF_TIMEOUT > 0 || ALL(HAS_WIRED_LCD, PRINTER_EVENT_LEDS) || (HAS_BACKLIGHT_TIMEOUT && defined(NEOPIXEL_BKGD_INDEX_FIRST))
|
||||||
#include "../feature/leds/leds.h"
|
#include "../feature/leds/leds.h"
|
||||||
|
@ -824,6 +825,13 @@ void MarlinUI::init() {
|
||||||
|
|
||||||
const feedRate_t fr_mm_s = (axis < LOGICAL_AXES) ? manual_feedrate_mm_s[axis] : XY_PROBE_FEEDRATE_MM_S;
|
const feedRate_t fr_mm_s = (axis < LOGICAL_AXES) ? manual_feedrate_mm_s[axis] : XY_PROBE_FEEDRATE_MM_S;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For a rotational axis apply the "inch" to "mm" conversion factor. This mimics behaviour of the G-code G1
|
||||||
|
* (see get_destination_from_command). For moves involving only rotational axes, the planner will convert
|
||||||
|
* back to the feedrate in degrees-per-time unit.
|
||||||
|
*/
|
||||||
|
const feedRate_t fr = parser.axis_is_rotational(axis) && parser.using_inch_units() ? IN_TO_MM(fr_mm_s) : fr_mm_s;
|
||||||
|
|
||||||
#if IS_KINEMATIC
|
#if IS_KINEMATIC
|
||||||
|
|
||||||
#if HAS_MULTI_EXTRUDER
|
#if HAS_MULTI_EXTRUDER
|
||||||
|
@ -850,13 +858,13 @@ void MarlinUI::init() {
|
||||||
// previous invocation is being blocked. Modifications to offset shouldn't be made while
|
// previous invocation is being blocked. Modifications to offset shouldn't be made while
|
||||||
// processing is true or the planner will get out of sync.
|
// processing is true or the planner will get out of sync.
|
||||||
processing = true;
|
processing = true;
|
||||||
prepare_internal_move_to_destination(fr_mm_s); // will set current_position from destination
|
prepare_internal_move_to_destination(fr); // will set current_position from destination
|
||||||
processing = false;
|
processing = false;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// For Cartesian / Core motion simply move to the current_position
|
// For Cartesian / Core motion simply move to the current_position
|
||||||
planner.buffer_line(current_position, fr_mm_s,
|
planner.buffer_line(current_position, fr,
|
||||||
TERN_(MULTI_E_MANUAL, axis == E_AXIS ? e_index :) active_extruder
|
TERN_(MULTI_E_MANUAL, axis == E_AXIS ? e_index :) active_extruder
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -78,8 +78,8 @@ void lcd_move_axis(const AxisEnum axis) {
|
||||||
if (ui.should_draw()) {
|
if (ui.should_draw()) {
|
||||||
MenuEditItemBase::itemIndex = axis;
|
MenuEditItemBase::itemIndex = axis;
|
||||||
const float pos = ui.manual_move.axis_value(axis);
|
const float pos = ui.manual_move.axis_value(axis);
|
||||||
if (parser.using_inch_units()) {
|
if (parser.using_inch_units() && !parser.axis_is_rotational(axis)) {
|
||||||
const float imp_pos = LINEAR_UNIT(pos);
|
const float imp_pos = parser.per_axis_value(axis, pos);
|
||||||
MenuEditItemBase::draw_edit_screen(GET_TEXT_F(MSG_MOVE_N), ftostr63(imp_pos));
|
MenuEditItemBase::draw_edit_screen(GET_TEXT_F(MSG_MOVE_N), ftostr63(imp_pos));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -1153,10 +1153,13 @@ float get_move_distance(const xyze_pos_t &diff OPTARG(HAS_ROTATIONAL_AXES, bool
|
||||||
|
|
||||||
#if HAS_ROTATIONAL_AXES
|
#if HAS_ROTATIONAL_AXES
|
||||||
if (UNEAR_ZERO(distance_sqr)) {
|
if (UNEAR_ZERO(distance_sqr)) {
|
||||||
// Move involves only rotational axes. Calculate angular distance in accordance with LinuxCNC
|
// Move involves no linear axes. Calculate angular distance in accordance with LinuxCNC
|
||||||
is_cartesian_move = false;
|
|
||||||
distance_sqr = ROTATIONAL_AXIS_GANG(sq(diff.i), + sq(diff.j), + sq(diff.k), + sq(diff.u), + sq(diff.v), + sq(diff.w));
|
distance_sqr = ROTATIONAL_AXIS_GANG(sq(diff.i), + sq(diff.j), + sq(diff.k), + sq(diff.u), + sq(diff.v), + sq(diff.w));
|
||||||
}
|
}
|
||||||
|
if (!UNEAR_ZERO(distance_sqr)) {
|
||||||
|
// Move involves rotational axes, not just the extruder
|
||||||
|
is_cartesian_move = false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2079,11 +2079,11 @@ bool Planner::_populate_block(
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This part of the code calculates the total length of the movement.
|
* This part of the code calculates the total length of the movement.
|
||||||
* For cartesian bots, the X_AXIS is the real X movement and same for Y_AXIS.
|
* For cartesian bots, the distance along the X axis equals the X_AXIS joint displacement and same holds true for Y_AXIS.
|
||||||
* But for corexy bots, that is not true. The "X_AXIS" and "Y_AXIS" motors (that should be named to A_AXIS
|
* But for geometries like CORE_XY that is not true. For these machines we need to create 2 additional variables, named X_HEAD and Y_HEAD, to store the displacent of the head along the X and Y axes in a cartesian coordinate system.
|
||||||
* and B_AXIS) cannot be used for X and Y length, because A=X+Y and B=X-Y.
|
* The displacement of the head along the axes of the cartesian coordinate system has to be calculated from "X_AXIS" and "Y_AXIS" (should be renamed to A_JOINT and B_JOINT)
|
||||||
* So we need to create other 2 "AXIS", named X_HEAD and Y_HEAD, meaning the real displacement of the Head.
|
* displacements in joints space using forward kinematics (A=X+Y and B=X-Y in the case of CORE_XY).
|
||||||
* Having the real displacement of the head, we can calculate the total movement length and apply the desired speed.
|
* Next we can calculate the total movement length and apply the desired speed.
|
||||||
*/
|
*/
|
||||||
struct DistanceMM : abce_float_t {
|
struct DistanceMM : abce_float_t {
|
||||||
#if ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX)
|
#if ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX)
|
||||||
|
@ -2308,6 +2308,10 @@ bool Planner::_populate_block(
|
||||||
// Example 2: At 120°/s a 60° move involving only rotational axes takes 0.5s. So this will give 2.0.
|
// Example 2: At 120°/s a 60° move involving only rotational axes takes 0.5s. So this will give 2.0.
|
||||||
float inverse_secs = inverse_millimeters * (
|
float inverse_secs = inverse_millimeters * (
|
||||||
#if ALL(HAS_ROTATIONAL_AXES, INCH_MODE_SUPPORT)
|
#if ALL(HAS_ROTATIONAL_AXES, INCH_MODE_SUPPORT)
|
||||||
|
/**
|
||||||
|
* Workaround for premature feedrate conversion
|
||||||
|
* from in/s to mm/s by get_distance_from_command.
|
||||||
|
*/
|
||||||
cartesian_move ? fr_mm_s : LINEAR_UNIT(fr_mm_s)
|
cartesian_move ? fr_mm_s : LINEAR_UNIT(fr_mm_s)
|
||||||
#else
|
#else
|
||||||
fr_mm_s
|
fr_mm_s
|
||||||
|
|
Loading…
Reference in a new issue