Skip to content

Commit d930f1d

Browse files
committed
fix G68, G69, add G50, G51
1 parent 003b136 commit d930f1d

File tree

11 files changed

+272
-151
lines changed

11 files changed

+272
-151
lines changed

Marlin/src/gcode/gcode.cpp

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,21 @@ relative_t GcodeSuite::axis_relative; // Init in constructor
100100
xyz_pos_t GcodeSuite::coordinate_system[MAX_COORDINATE_SYSTEMS];
101101
#endif
102102

103+
#if ENABLED(SCALE_WORKSPACE)
104+
float GcodeSuite::scaling_center_x = 0.0f;
105+
float GcodeSuite::scaling_center_y = 0.0f;
106+
float GcodeSuite::scaling_center_z = 0.0f;
107+
float GcodeSuite::scaling_factor_x = 1.0f;
108+
float GcodeSuite::scaling_factor_y = 1.0f;
109+
float GcodeSuite::scaling_factor_z = 1.0f;
110+
#endif
111+
112+
#if ENABLED(ROTATE_WORKSPACE)
113+
float GcodeSuite::rotation_center_x = 0.0f;
114+
float GcodeSuite::rotation_center_y = 0.0f;
115+
float GcodeSuite::rotation_angle = 0.0f;
116+
#endif
117+
103118
void GcodeSuite::report_echo_start(const bool forReplay) { if (!forReplay) SERIAL_ECHO_START(); }
104119
void GcodeSuite::report_heading(const bool forReplay, FSTR_P const fstr, const bool eol/*=true*/) {
105120
if (forReplay) return;
@@ -171,19 +186,58 @@ void GcodeSuite::get_destination_from_command() {
171186
constexpr bool skip_move = false;
172187
#endif
173188

189+
const float angle_rad = RADIANS(rotation_angle);
190+
174191
// Get new XYZ position, whether absolute or relative
175192
LOOP_NUM_AXES(i) {
176193
if ( (seen[i] = parser.seenval(AXIS_CHAR(i))) ) {
177194
const float v = parser.value_axis_units((AxisEnum)i);
178-
if (skip_move)
195+
if (skip_move) {
196+
#if ENABLED(ROTATE_WORKSPACE)
197+
raw_destination[i] = current_position[i];
198+
#else
199+
destination[i] = current_position[i];
200+
#endif
201+
}
202+
else {
203+
#if ENABLED(ROTATE_WORKSPACE)
204+
raw_destination[i] = axis_is_relative(AxisEnum(i)) ? raw_destination[i] + v : LOGICAL_TO_NATIVE(v, i);
205+
#else
206+
destination[i] = axis_is_relative(AxisEnum(i)) ? current_position[i] + v : LOGICAL_TO_NATIVE(v, i);
207+
#endif
208+
}
209+
}
210+
else {
211+
#if DISABLED(ROTATE_WORKSPACE)
179212
destination[i] = current_position[i];
180-
else
181-
destination[i] = axis_is_relative(AxisEnum(i)) ? current_position[i] + v : LOGICAL_TO_NATIVE(v, i);
213+
#endif
182214
}
183-
else
184-
destination[i] = current_position[i];
185215
}
186216

217+
#if ANY(SCALE_WORKSPACE, ROTATE_WORKPLACE)
218+
destination = raw_destination;
219+
#endif
220+
221+
#if ENABLED(SCALE_WORKSPACE)
222+
if (!(NEAR(scaling_factor_x, 1.0f) || NEAR(scaling_factor_y, 1.0f) || NEAR(scaling_factor_z, 1.0f))) {
223+
destination.x = (raw_destination.x - scaling_center_x) * scaling_factor_x + scaling_center_x;
224+
TERN_(HAS_Y_AXIS, destination.y = (raw_destination.y - scaling_center_y) * scaling_factor_y + scaling_center_y);
225+
TERN_(HAS_Z_AXIS, destination.z = (raw_destination.z - scaling_center_z) * scaling_factor_z + scaling_center_z);
226+
}
227+
#endif
228+
229+
#if ENABLED(ROTATE_WORKSPACE)
230+
if (!NEAR_ZERO(rotation_angle)) {
231+
const float cos_angle = cos(angle_rad);
232+
const float sin_angle = sin(angle_rad);
233+
// Apply rotation
234+
const float temp_x = destination.x - rotation_center_x;
235+
const float temp_y = destination.y - rotation_center_y;
236+
destination.x = temp_x * cos_angle - temp_y * sin_angle + rotation_center_x;
237+
destination.y = temp_x * sin_angle + temp_y * cos_angle + rotation_center_y;
238+
}
239+
#endif
240+
187241
#if HAS_EXTRUDERS
188242
// Get new E position, whether absolute or relative
189243
if ( (seen.e = parser.seenval('E')) ) {
@@ -435,6 +489,11 @@ void GcodeSuite::process_parsed_command(bool no_ok/*=false*/) {
435489
case 42: G42(); break; // G42: Coordinated move to a mesh point
436490
#endif
437491

492+
#if ENABLED(SCALE_WORKSPACE)
493+
case 50: G50(); break; // G50: Cancel Workspace Scaling
494+
case 51: G51(); break; // G51: Set Workspace Scaling
495+
#endif
496+
438497
#if ENABLED(CNC_COORDINATE_SYSTEMS)
439498
case 53: G53(); break; // G53: (prefix) Apply native workspace
440499
case 54: G54(); break; // G54: Switch to Workspace 1
@@ -452,6 +511,7 @@ void GcodeSuite::process_parsed_command(bool no_ok/*=false*/) {
452511

453512
#if ENABLED(ROTATE_WORKSPACE)
454513
case 68: G68(); break; // G68: Set Workspace Rotation
514+
case 69: G69(); break; // G69: Cancel Workspace Rotation
455515
#endif
456516

457517
#if ALL(PTC_PROBE, PTC_BED)

Marlin/src/gcode/gcode.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,12 @@
6464
* G35 - Read bed corners to help adjust bed screws: T<screw_thread> (Requires ASSISTED_TRAMMING)
6565
* G38 - Probe in any direction using the Z_MIN_PROBE (Requires G38_PROBE_TARGET)
6666
* G42 - Coordinated move to a mesh point (Requires MESH_BED_LEVELING, AUTO_BED_LEVELING_BLINEAR, or AUTO_BED_LEVELING_UBL)
67+
* G50 - Cancel workspace scaling (Requires SCALE_WORKSPACE)
68+
* G51 - Set workspace scaling (Requires SCALE_WORKSPACE)
6769
* G60 - Save current position. (Requires SAVED_POSITIONS)
6870
* G61 - Apply/Restore saved coordinates. (Requires SAVED_POSITIONS)
6971
* G68 - Set Workspace Rotation
72+
* G69 - Cancel Workspace Rotation
7073
* G76 - Calibrate first layer temperature offsets. (Requires PTC_PROBE and PTC_BED)
7174
* G80 - Cancel current motion mode (Requires GCODE_MOTION_MODES)
7275
* G90 - Use Absolute Coordinates
@@ -432,12 +435,20 @@ class GcodeSuite {
432435
static bool select_coordinate_system(const int8_t _new);
433436
#endif
434437

438+
439+
#if ENABLED(SCALE_WORKSPACE)
440+
static float scaling_center_x;
441+
static float scaling_center_y;
442+
static float scaling_center_z;
443+
static float scaling_factor_x;
444+
static float scaling_factor_y;
445+
static float scaling_factor_z;
446+
#endif
447+
435448
#if ENABLED(ROTATE_WORKSPACE)
436-
static uint8_t active_workspace;
437-
static float rotation_angle[MAX_COORDINATE_SYSTEMS]; // Store rotation for each workspace
449+
static float rotation_angle;
438450
static float rotation_center_x;
439451
static float rotation_center_y;
440-
static void apply_workspace_rotation();
441452
#endif
442453

443454
static millis_t previous_move_ms, max_inactive_time;
@@ -618,7 +629,11 @@ class GcodeSuite {
618629
static void G42();
619630
#endif
620631

621-
#if ENABLED(CNC_COORDINATE_SYSTEMS)
632+
#if ENABLED(SCALE_WORKSPACE)
633+
static void G50();
634+
static void G51();
635+
#endif
636+
622637
static void G53();
623638
static void G54();
624639
static void G55();
@@ -639,6 +654,7 @@ class GcodeSuite {
639654

640655
#if ENABLED(ROTATE_WORKSPACE)
641656
static void G68();
657+
static void G69();
642658
#endif
643659

644660
#if ENABLED(GCODE_MOTION_MODES)

Marlin/src/gcode/geometry/G17-G19.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,13 @@ inline void report_workspace_plane() {
3737
}
3838

3939
inline void set_workspace_plane(const GcodeSuite::WorkspacePlane plane) {
40-
gcode.workspace_plane = plane;
41-
if (DEBUGGING(INFO)) report_workspace_plane();
40+
if (!NEAR_ZERO(gcode.rotation_angle)) {
41+
SERIAL_ECHOLNPGM("Error: Workspace plane cannnot change while using workspace rotation.");
42+
}
43+
else {
44+
gcode.workspace_plane = plane;
45+
if (DEBUGGING(INFO)) report_workspace_plane();
46+
}
4247
}
4348

4449
/**
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/**
2+
* Marlin 3D Printer Firmware
3+
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4+
*
5+
* Based on Sprinter and grbl.
6+
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU General Public License as published by
10+
* the Free Software Foundation, either version 3 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public License
19+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
20+
*
21+
*/
22+
23+
#include "../../inc/MarlinConfigPre.h"
24+
25+
#if ENABLED(SCALE_WORKSPACE)
26+
27+
#include "../gcode.h"
28+
#include "../../module/motion.h"
29+
30+
/**
31+
* G51: Set Workspace Scaling
32+
*
33+
* Scale the current workspace coordinate system.
34+
*
35+
* Parameters:
36+
* X<axis units> x coordinate of the scaling center
37+
* Y<axis units> y coordinate of the scaling center
38+
* Z<axis units> z coordinate of the scaling center
39+
* I<scaling factor> scaling factor for X axis
40+
* J<scaling factor> scaling factor for Y axis
41+
* K<scaling factor> scaling factor for Z axis
42+
* P<scaling factor> scaling factor
43+
*/
44+
45+
void GcodeSuite::G51() {
46+
47+
if (parser.seenval('P')) {
48+
const float scaling_factor = parser.value_float();
49+
scaling_factor_x = scaling_factor;
50+
TERN_(HAS_Y_AXIS, scaling_factor_y = scaling_factor);
51+
TERN_(HAS_Z_AXIS, scaling_factor_z = scaling_factor);
52+
}
53+
else {
54+
if (parser.seenval('I'))
55+
scaling_factor_x = parser.value_float();
56+
#if HAS_Y_AXIS
57+
if (parser.seenval('J'))
58+
scaling_factor_y = parser.value_float();
59+
#endif
60+
#if HAS_Z_AXIS
61+
if (parser.seenval('K'))
62+
scaling_factor_z = parser.value_float();
63+
#endif
64+
}
65+
66+
scaling_center_x = parser.seenval('X') ? LOGICAL_TO_NATIVE(parser.value_axis_units(X_AXIS), X_AXIS) : current_position.x;
67+
TERN_(HAS_Y_AXIS, scaling_center_y = parser.seenval('Y') ? LOGICAL_TO_NATIVE(parser.value_axis_units(Y_AXIS), Y_AXIS) : current_position.y);
68+
TERN_(HAS_Z_AXIS, scaling_center_z = parser.seenval('Z') ? LOGICAL_TO_NATIVE(parser.value_axis_units(Z_AXIS), Z_AXIS) : current_position.z);
69+
70+
SERIAL_ECHOLNPGM("Workspace scaling set");
71+
}
72+
73+
void GcodeSuite::G50() {
74+
scaling_factor_x = 1.0f;
75+
scaling_center_x = 0.0f;
76+
scaling_factor_y = 1.0f;
77+
scaling_center_y = 0.0f;
78+
#if HAS_Z_AXIS
79+
scaling_factor_z = 1.0f;
80+
scaling_center_z = 0.0f;
81+
#endif
82+
SERIAL_ECHOLNPGM("Workspace scaling canceled");
83+
}
84+
85+
86+
#endif // SCALE_WORKSPACE

Marlin/src/gcode/geometry/G53-G59.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
*/
3434
bool GcodeSuite::select_coordinate_system(const int8_t _new) {
3535
if (active_coordinate_system == _new) return false;
36+
if (!NEAR_ZERO(gcode.rotation_angle)) {
37+
SERIAL_ECHOLNPGM("Cannot change workspace while workspace rotation is active");
38+
return false;
39+
}
3640
active_coordinate_system = _new;
3741
xyz_float_t new_offset{0};
3842
if (WITHIN(_new, 0, MAX_COORDINATE_SYSTEMS - 1))
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* Marlin 3D Printer Firmware
3+
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4+
*
5+
* Based on Sprinter and grbl.
6+
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU General Public License as published by
10+
* the Free Software Foundation, either version 3 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public License
19+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
20+
*
21+
*/
22+
23+
#include "../../inc/MarlinConfigPre.h"
24+
25+
#if ENABLED(ROTATE_WORKSPACE)
26+
27+
#include "../gcode.h"
28+
#include "../../module/motion.h"
29+
30+
/**
31+
* G68: Set Workspace Rotation
32+
*
33+
* Set the rotation (about Z axis) for the current workspace (begins at 0).
34+
*
35+
* Parameters:
36+
* X<axis units> x coordinate of the rotation center for the current workspace
37+
* Y<axis units> y coordinate of the rotation center for the current workspace
38+
* R<deg> Rotation angle in degrees (Required)
39+
*
40+
* Example:
41+
* G68 R45 ; Rotate active workspace by 45° counter-clockwise (when viewed from positive Z)
42+
* ; around current position
43+
* G68 R-30 ; Rotate active workspace by -30° around current position
44+
* G68 X0 Y0 R45 ; Rotate active workspace by 45°C around X0 Y0 (X and Y are specified in the current workspace)
45+
*
46+
* NOTES:
47+
* - Only rotation is set. No translation/offset is changed.
48+
* - All subsequent moves are rotated by the specified angle.
49+
* - It is an error to change workspace or working plane while workspace rotation is active
50+
* (https://forums.autodesk.com/t5/fusion-manufacture-forum/probing-and-updating-wcs-for-angle/td-p/9487027 ,
51+
* https://www.machsupport.com/forum/index.php?topic=43012)
52+
*/
53+
54+
void GcodeSuite::G68() {
55+
56+
if (!parser.seenval('R')) {
57+
SERIAL_ECHOLNPGM("Missing R parameter (rotation angle).");
58+
return;
59+
}
60+
else {
61+
rotation_angle = parser.value_float();
62+
}
63+
TERN_(HAS_X_AXIS, rotation_center_x = parser.seenval('X') ? LOGICAL_TO_NATIVE(parser.value_axis_units(X_AXIS), X_AXIS) : current_position.x);
64+
TERN_(HAS_Y_AXIS, rotation_center_y = parser.seenval('Y') ? LOGICAL_TO_NATIVE(parser.value_axis_units(Y_AXIS), Y_AXIS) : current_position.y);
65+
SERIAL_ECHOLNPGM("Workspace rotation set");
66+
}
67+
68+
void GcodeSuite::G69() {
69+
rotation_angle = 0.0f;
70+
SERIAL_ECHOLNPGM("Workspace rotation canceled");
71+
}
72+
73+
74+
#endif // ROTATE_WORKSPACE

Marlin/src/gcode/motion/G0_G1.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@
4141

4242
extern xyze_pos_t destination;
4343

44+
#if defined(ROTATE_WORKSPACE)
45+
extern xyz_pos_t raw_destination;
46+
#endif
47+
4448
#if ENABLED(VARIABLE_G0_FEEDRATE)
4549
feedRate_t fast_move_feedrate = MMM_TO_MMS(G0_FEEDRATE);
4650
#endif

0 commit comments

Comments
 (0)