From 8f09d68f45c258a701d7fcde58b694011aa9e5b4 Mon Sep 17 00:00:00 2001 From: Luca Toniolo <10792599+grandixximo@users.noreply.github.com> Date: Tue, 10 Nov 2026 13:32:39 +1100 Subject: [PATCH] interp: keep the current point when G10 L2 turns the system in effect under G92 The current point is in program coordinates, with G92 inside the XY rotation of the coordinate system: world = G5x + R * (point + G92). When G10 L2 changed R of the system in effect, the interpreter turned the point without its G92 and turned it back the same way, so with a G92 in effect it lost track of where the tool is until task resynchronised it from the machine. Within a program nothing does that: G54 at R0, the tool at X5 Y0, G92 X0 Y0, then G10 L2 P1 R90 leaves the tool at X-5 Y-5 of the turned system, but the interpreter had X0 Y0. A G91 G0 X0 Y0 on the next line, which should not move, moved the tool 7 mm to X0 Y5 of the machine, and a G91 G2 X0 Y2 I0 J1 ended at X-2 Y5 instead of X3 Y0. In MDI, task resynchronises the interpreter between commands, so it did not show there. The change now takes the current point through the whole chain to the machine frame before it and back after it, with program_to_world_xyz() and world_to_program_xyz(), as selecting a coordinate system and the tilted work plane already do. Fanuc, Heidenhain and Siemens also take the program position from the machine position after an offset change. A G10 L2 that changes only the origin, G10 L20 and selecting a system behaved correctly before and give the same result now; G10 L20's own fix-up of the point, which the round trip replaces, is gone. tests/interp/rotation/abs-pts changes R on G54 with a G92 in effect and reads the absolute position back: wrong on master, 1 2 3 here. --- src/emc/rs274ngc/interp_convert.cc | 33 +++++++++++--------------- tests/interp/rotation/abs-pts/expected | 4 ++++ tests/interp/rotation/abs-pts/test.ngc | 11 +++++++++ 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/emc/rs274ngc/interp_convert.cc b/src/emc/rs274ngc/interp_convert.cc index f3a00c02e6a..21a2f65c4d8 100644 --- a/src/emc/rs274ngc/interp_convert.cc +++ b/src/emc/rs274ngc/interp_convert.cc @@ -5038,6 +5038,15 @@ int Interp::convert_setup(block_pointer block, //!< pointer to a block of RS27 &ca, &cb, &cc, &cu, &cv, &cw); + // the tool stays where it is: its X Y Z go round the chain, G92 + // included, before the change and back after it + bool in_use = p_int == settings->origin_index; + double wx = 0, wy = 0, wz = 0; + if (in_use) { + program_to_world_xyz(settings, settings->current_x, settings->current_y, + settings->current_z, &wx, &wy, &wz); + } + if (block->r_flag) { CHKS((block->l_number == 20), _("R not allowed in G10 L20")); r = block->r_number; @@ -5072,12 +5081,6 @@ int Interp::convert_setup(block_pointer block, //!< pointer to a block of RS27 // parameters are not rotated parameters[5201 + (p_int * 20)] = PROGRAM_TO_USER_LEN(x); parameters[5202 + (p_int * 20)] = PROGRAM_TO_USER_LEN(y); - - if (p_int == settings->origin_index) { - // let the code below fix up the current coordinates correctly - rotate(&settings->current_x, &settings->current_y, settings->rotation_xy); - settings->rotation_xy = 0; - } } else { if (block->x_flag) { x = block->x_number; @@ -5142,13 +5145,7 @@ int Interp::convert_setup(block_pointer block, //!< pointer to a block of RS27 } else w = USER_TO_PROGRAM_AX(AXIS_W, parameters[5209 + (p_int * 20)]); - if (p_int == settings->origin_index) { /* system is currently used */ - - rotate(&settings->current_x, &settings->current_y, settings->rotation_xy); - - settings->current_x += settings->origin_offset_x; - settings->current_y += settings->origin_offset_y; - settings->current_z += settings->origin_offset_z; + if (in_use) { settings->AA_current += settings->AA_origin_offset; settings->BB_current += settings->BB_origin_offset; settings->CC_current += settings->CC_origin_offset; @@ -5166,9 +5163,6 @@ int Interp::convert_setup(block_pointer block, //!< pointer to a block of RS27 settings->v_origin_offset = v; settings->w_origin_offset = w; - settings->current_x -= x; - settings->current_y -= y; - settings->current_z -= z; settings->AA_current -= a; settings->BB_current -= b; settings->CC_current -= c; @@ -5176,10 +5170,11 @@ int Interp::convert_setup(block_pointer block, //!< pointer to a block of RS27 settings->v_current -= v; settings->w_current -= w; - SET_G5X_OFFSET(p_int, x, y, z, a, b, c, u, v, w); - - rotate(&settings->current_x, &settings->current_y, - r); settings->rotation_xy = r; + world_to_program_xyz(settings, wx, wy, wz, &settings->current_x, + &settings->current_y, &settings->current_z); + + SET_G5X_OFFSET(p_int, x, y, z, a, b, c, u, v, w); SET_XY_ROTATION(settings->rotation_xy); } diff --git a/tests/interp/rotation/abs-pts/expected b/tests/interp/rotation/abs-pts/expected index 5131a8c2b89..d3989917383 100644 --- a/tests/interp/rotation/abs-pts/expected +++ b/tests/interp/rotation/abs-pts/expected @@ -12,6 +12,8 @@ N..... MESSAGE("1.000000 2.000000 3.000000") N..... MESSAGE("0.000000 0.000000 0.000000") N..... MESSAGE("1.000000 2.000000 3.000000") + N..... MESSAGE("1.000000 2.000000 3.000000") + N..... MESSAGE("1.000000 2.000000 3.000000") N..... MESSAGE("0.000000 0.000000 0.000000") N..... MESSAGE("1.000000 2.000000 3.000000") N..... MESSAGE("0.000000 0.000000 0.000000") @@ -26,3 +28,5 @@ N..... MESSAGE("1.000000 2.000000 3.000000") N..... MESSAGE("0.000000 0.000000 0.000000") N..... MESSAGE("1.000000 2.000000 3.000000") + N..... MESSAGE("1.000000 2.000000 3.000000") + N..... MESSAGE("1.000000 2.000000 3.000000") diff --git a/tests/interp/rotation/abs-pts/test.ngc b/tests/interp/rotation/abs-pts/test.ngc index 29a0e315012..f84fed86cd0 100644 --- a/tests/interp/rotation/abs-pts/test.ngc +++ b/tests/interp/rotation/abs-pts/test.ngc @@ -37,6 +37,17 @@ g10l2p1x3y7z0r45 g92x3y7 o call g92.2 + +; the rotation of the system in effect changes under a G92: the current +; point stays where it is +g10l2p1x3y7z0r0 +g92x3y7 +g53g0x1y2z3 +g10l2p1r45 +(debug,#<_abs_x> #<_abs_y> #<_abs_z>) +g10l2p1r0 +(debug,#<_abs_x> #<_abs_y> #<_abs_z>) +g92.2 o endsub g20