Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better support for "infinite" axes: Enable G92.9 (directly set current position) for rotational axes #26174

Merged
merged 17 commits into from
Mar 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Marlin/src/gcode/geometry/G92.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.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].
*/
void GcodeSuite::G92() {
Expand All @@ -67,7 +67,7 @@ void GcodeSuite::G92() {
break;
#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)
LOOP_LOGICAL_AXES(i) {
if (parser.seenval(AXIS_CHAR(i))) {
Expand Down
2 changes: 1 addition & 1 deletion Marlin/src/inc/Conditionals_post.h
Original file line number Diff line number Diff line change
Expand Up @@ -3276,7 +3276,7 @@
#endif

// 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
#endif

Expand Down
12 changes: 10 additions & 2 deletions Marlin/src/lcd/marlinui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "../inc/MarlinConfig.h"

#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))
#include "../feature/leds/leds.h"
Expand Down Expand Up @@ -851,6 +852,13 @@ void MarlinUI::init() {

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 HAS_MULTI_EXTRUDER
Expand All @@ -877,13 +885,13 @@ void MarlinUI::init() {
// 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 = 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;

#else

// 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
);

Expand Down
4 changes: 2 additions & 2 deletions Marlin/src/lcd/menu/menu_motion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ void lcd_move_axis(const AxisEnum axis) {
if (ui.should_draw()) {
MenuEditItemBase::itemIndex = axis;
const float pos = ui.manual_move.axis_value(axis);
if (parser.using_inch_units()) {
const float imp_pos = LINEAR_UNIT(pos);
if (parser.using_inch_units() && !parser.axis_is_rotational(axis)) {
const float imp_pos = parser.per_axis_value(axis, pos);
MenuEditItemBase::draw_edit_screen(GET_TEXT_F(MSG_MOVE_N), ftostr63(imp_pos));
}
else
Expand Down
7 changes: 5 additions & 2 deletions Marlin/src/module/motion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1154,10 +1154,13 @@ float get_move_distance(const xyze_pos_t &diff OPTARG(HAS_ROTATIONAL_AXES, bool

#if HAS_ROTATIONAL_AXES
if (UNEAR_ZERO(distance_sqr)) {
// Move involves only rotational axes. Calculate angular distance in accordance with LinuxCNC
is_cartesian_move = false;
// Move involves no linear axes. Calculate angular distance in accordance with LinuxCNC
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
Expand Down
14 changes: 9 additions & 5 deletions Marlin/src/module/planner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2079,11 +2079,11 @@ bool Planner::_populate_block(

/**
* 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.
* But for corexy bots, that is not true. The "X_AXIS" and "Y_AXIS" motors (that should be named to A_AXIS
* and B_AXIS) cannot be used for X and Y length, because A=X+Y and B=X-Y.
* So we need to create other 2 "AXIS", named X_HEAD and Y_HEAD, meaning the real displacement of the Head.
* Having the real displacement of the head, we can calculate the total movement length and apply the desired speed.
* For cartesian bots, the distance along the X axis equals the X_AXIS joint displacement and same holds true for Y_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.
* 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)
* displacements in joints space using forward kinematics (A=X+Y and B=X-Y in the case of CORE_XY).
* Next we can calculate the total movement length and apply the desired speed.
*/
struct DistanceMM : abce_float_t {
#if ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX)
Expand Down Expand Up @@ -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.
float inverse_secs = inverse_millimeters * (
#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)
#else
fr_mm_s
Expand Down
Loading