🚸 Enable G92.9 with rotational axes (#26174)

- Supporting axes that can rotate forever.
This commit is contained in:
DerAndere 2024-03-02 04:16:39 +01:00 committed by GitHub
parent d609bb4671
commit c8d51c2723
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 29 additions and 14 deletions

View file

@ -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() {
@ -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))) {

View file

@ -3279,7 +3279,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

View file

@ -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"
@ -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;
/**
* 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
@ -850,13 +858,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
);

View file

@ -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

View file

@ -1153,10 +1153,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

View file

@ -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)
@ -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