Skip to content

Commit

Permalink
✨ Polargraph / Makelangelo kinematics (MarlinFirmware#22790)
Browse files Browse the repository at this point in the history
  • Loading branch information
i-make-robots authored and pull[bot] committed Oct 4, 2021
1 parent 359ca42 commit d3ddfa2
Show file tree
Hide file tree
Showing 24 changed files with 297 additions and 97 deletions.
7 changes: 7 additions & 0 deletions Marlin/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,13 @@
// Enable for a belt style printer with endless "Z" motion
//#define BELTPRINTER

// Enable for Polargraph Kinematics
//#define POLARGRAPH
#if ENABLED(POLARGRAPH)
#define POLARGRAPH_MAX_BELT_LEN 1035.0
#define POLAR_SEGMENTS_PER_SECOND 5
#endif

//===========================================================================
//============================== Endstop Settings ===========================
//===========================================================================
Expand Down
2 changes: 2 additions & 0 deletions Marlin/src/MarlinCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@

#if ENABLED(DELTA)
#include "module/delta.h"
#elif ENABLED(POLARGRAPH)
#include "module/polargraph.h"
#elif IS_SCARA
#include "module/scara.h"
#endif
Expand Down
7 changes: 4 additions & 3 deletions Marlin/src/core/language.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,10 @@
// Settings Report Strings
#define STR_Z_AUTO_ALIGN "Z Auto-Align"
#define STR_BACKLASH_COMPENSATION "Backlash compensation"
#define STR_DELTA_SETTINGS "Delta settings (L<diagonal-rod> R<radius> H<height> S<segments-per-sec> XYZ<tower-angle-trim> ABC<rod-trim>)"
#define STR_SCARA_SETTINGS "SCARA settings"
#define STR_SCARA_S "S<seg-per-sec>"
#define STR_S_SEG_PER_SEC "S<seg-per-sec>"
#define STR_DELTA_SETTINGS "Delta (L<diagonal-rod> R<radius> H<height> S<seg-per-sec> XYZ<tower-angle-trim> ABC<rod-trim>)"
#define STR_SCARA_SETTINGS "SCARA"
#define STR_POLARGRAPH_SETTINGS "Polargraph"
#define STR_SCARA_P_T_Z "P<theta-psi-offset> T<theta-offset> Z<home-offset>"
#define STR_ENDSTOP_ADJUSTMENT "Endstop adjustment"
#define STR_SKEW_FACTOR "Skew Factor"
Expand Down
2 changes: 2 additions & 0 deletions Marlin/src/feature/bedlevel/ubl/ubl_motion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,8 @@
#define DELTA_SEGMENT_MIN_LENGTH 0.25 // SCARA minimum segment size is 0.25mm
#elif ENABLED(DELTA)
#define DELTA_SEGMENT_MIN_LENGTH 0.10 // mm (still subject to DELTA_SEGMENTS_PER_SECOND)
#elif ENABLED(POLARGRAPH)
#define DELTA_SEGMENT_MIN_LENGTH 0.10 // mm (still subject to DELTA_SEGMENTS_PER_SECOND)
#else // CARTESIAN
#ifdef LEVELED_SEGMENT_LENGTH
#define DELTA_SEGMENT_MIN_LENGTH LEVELED_SEGMENT_LENGTH
Expand Down
25 changes: 24 additions & 1 deletion Marlin/src/gcode/calibrate/M665.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@
}

void GcodeSuite::M665_report(const bool forReplay/*=true*/) {
report_heading_etc(forReplay, PSTR(STR_SCARA_SETTINGS " (" STR_SCARA_S TERN_(HAS_SCARA_OFFSET, " " STR_SCARA_P_T_Z) ")"));
report_heading_etc(forReplay, PSTR(STR_SCARA_SETTINGS " (" STR_S_SEG_PER_SEC TERN_(HAS_SCARA_OFFSET, " " STR_SCARA_P_T_Z) ")"));
SERIAL_ECHOLNPGM_P(
PSTR(" M665 S"), segments_per_second
#if HAS_SCARA_OFFSET
Expand All @@ -143,6 +143,29 @@
);
}

#elif ENABLED(POLARGRAPH)

#include "../../module/polargraph.h"

/**
* M665: Set POLARGRAPH settings
*
* Parameters:
*
* S[segments-per-second] - Segments-per-second
*/
void GcodeSuite::M665() {
if (parser.seenval('S'))
segments_per_second = parser.value_float();
else
M665_report();
}

void GcodeSuite::M665_report(const bool forReplay/*=true*/) {
report_heading_etc(forReplay, PSTR(STR_POLARGRAPH_SETTINGS " (" STR_S_SEG_PER_SEC ")"));
SERIAL_ECHOLNPGM(" M665 S", segments_per_second);
}

#endif

#endif // IS_KINEMATIC
36 changes: 29 additions & 7 deletions Marlin/src/gcode/control/M280.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,44 @@

#include "../gcode.h"
#include "../../module/servo.h"
#include "../../module/planner.h"

/**
* M280: Get or set servo position. P<index> [S<angle>]
* M280: Get or set servo position.
* P<index> - Servo index
* S<angle> - Angle to set, omit to read current angle, or use -1 to detach
*
* With POLARGRAPH:
* T<ms> - Duration of servo move
*/
void GcodeSuite::M280() {

if (!parser.seen('P')) return;
if (!parser.seenval('P')) return;

TERN_(POLARGRAPH, planner.synchronize());

const int servo_index = parser.value_int();
if (WITHIN(servo_index, 0, NUM_SERVOS - 1)) {
if (parser.seen('S')) {
const int a = parser.value_int();
if (a == -1)
DETACH_SERVO(servo_index);
if (parser.seenval('S')) {
const int anew = parser.value_int();
if (anew >= 0) {
#if ENABLED(POLARGRAPH)
if (parser.seen('T')) { // (ms) Total duration of servo move
const int16_t t = constrain(parser.value_int(), 0, 10000);
const int aold = servo[servo_index].read();
millis_t now = millis();
const millis_t start = now, end = start + t;
while (PENDING(now, end)) {
safe_delay(50);
now = _MIN(millis(), end);
MOVE_SERVO(servo_index, LROUND(aold + (anew - aold) * (float(now - start) / t)));
}
}
#endif // POLARGRAPH
MOVE_SERVO(servo_index, anew);
}
else
MOVE_SERVO(servo_index, a);
DETACH_SERVO(servo_index);
}
else
SERIAL_ECHO_MSG(" Servo ", servo_index, ": ", servo[servo_index].read());
Expand Down
2 changes: 1 addition & 1 deletion Marlin/src/gcode/control/M282.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
*/
void GcodeSuite::M282() {

if (!parser.seen('P')) return;
if (!parser.seenval('P')) return;

const int servo_index = parser.value_int();
if (WITHIN(servo_index, 0, NUM_SERVOS - 1))
Expand Down
4 changes: 2 additions & 2 deletions Marlin/src/gcode/gcode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -885,8 +885,8 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 605: M605(); break; // M605: Set Dual X Carriage movement mode
#endif

#if ENABLED(DELTA)
case 665: M665(); break; // M665: Set delta configurations
#if IS_KINEMATIC
case 665: M665(); break; // M665: Set Delta/SCARA parameters
#endif

#if ENABLED(DELTA) || HAS_EXTRA_ENDSTOPS
Expand Down
1 change: 1 addition & 0 deletions Marlin/src/gcode/gcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@
* M603 - Configure filament change: "M603 T<tool> U<unload_length> L<load_length>". (Requires ADVANCED_PAUSE_FEATURE)
* M605 - Set Dual X-Carriage movement mode: "M605 S<mode> [X<x_offset>] [R<temp_offset>]". (Requires DUAL_X_CARRIAGE)
* M665 - Set delta configurations: "M665 H<delta height> L<diagonal rod> R<delta radius> S<segments/s> B<calibration radius> X<Alpha angle trim> Y<Beta angle trim> Z<Gamma angle trim> (Requires DELTA)
* Set SCARA configurations: "M665 S<segments-per-second> P<theta-psi-offset> T<theta-offset> Z<z-offset> (Requires MORGAN_SCARA or MP_SCARA)
* M666 - Set/get offsets for delta (Requires DELTA) or dual endstops. (Requires [XYZ]_DUAL_ENDSTOPS)
* M672 - Set/Reset Duet Smart Effector's sensitivity. (Requires DUET_SMART_EFFECTOR and SMART_EFFECTOR_MOD_PIN)
* M701 - Load filament (Requires FILAMENT_LOAD_UNLOAD_GCODES)
Expand Down
2 changes: 1 addition & 1 deletion Marlin/src/inc/Conditionals_LCD.h
Original file line number Diff line number Diff line change
Expand Up @@ -1075,7 +1075,7 @@
#if ANY(MORGAN_SCARA, MP_SCARA, AXEL_TPARA)
#define IS_SCARA 1
#define IS_KINEMATIC 1
#elif ENABLED(DELTA)
#elif EITHER(DELTA, POLARGRAPH)
#define IS_KINEMATIC 1
#else
#define IS_CARTESIAN 1
Expand Down
4 changes: 2 additions & 2 deletions Marlin/src/inc/SanityCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -1340,8 +1340,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
/**
* Servo deactivation depends on servo endstops, switching nozzle, or switching extruder
*/
#if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE) && !HAS_Z_SERVO_PROBE && !defined(SWITCHING_NOZZLE_SERVO_NR) && !defined(SWITCHING_EXTRUDER_SERVO_NR) && !defined(SWITCHING_TOOLHEAD_SERVO_NR)
#error "Z_PROBE_SERVO_NR, switching nozzle, switching toolhead or switching extruder is required for DEACTIVATE_SERVOS_AFTER_MOVE."
#if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE) && NONE(HAS_Z_SERVO_PROBE, POLARGRAPH) && !defined(SWITCHING_NOZZLE_SERVO_NR) && !defined(SWITCHING_EXTRUDER_SERVO_NR) && !defined(SWITCHING_TOOLHEAD_SERVO_NR)
#error "Z_PROBE_SERVO_NR, switching nozzle, switching toolhead, switching extruder, or POLARGRAPH is required for DEACTIVATE_SERVOS_AFTER_MOVE."
#endif

/**
Expand Down
6 changes: 4 additions & 2 deletions Marlin/src/lcd/menu/menu_advanced.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -466,9 +466,11 @@ void menu_backlash();
#ifdef MAX_JERK_EDIT_VALUES
MAX_JERK_EDIT_VALUES
#elif ENABLED(LIMITED_JERK_EDITING)
{ (DEFAULT_XJERK) * 2, (DEFAULT_YJERK) * 2, (DEFAULT_ZJERK) * 2, (DEFAULT_EJERK) * 2 }
{ LOGICAL_AXIS_LIST((DEFAULT_EJERK) * 2,
(DEFAULT_XJERK) * 2, (DEFAULT_YJERK) * 2, (DEFAULT_ZJERK) * 2,
(DEFAULT_IJERK) * 2, (DEFAULT_JJERK) * 2, (DEFAULT_KJERK) * 2) }
#else
{ 990, 990, 990, 990 }
{ LOGICAL_AXIS_LIST(990, 990, 990, 990, 990, 990, 990) }
#endif
;
#define EDIT_JERK(N) EDIT_ITEM_FAST(float3, MSG_V##N##_JERK, &planner.max_jerk[_AXIS(N)], 1, max_jerk_edit[_AXIS(N)])
Expand Down
2 changes: 1 addition & 1 deletion Marlin/src/module/motion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ void do_blocking_move_to(LINEAR_AXIS_ARGS(const float), const_feedRate_t fr_mm_s
const feedRate_t z_feedrate = fr_mm_s ?: homing_feedrate(Z_AXIS);
#endif

#if EITHER(DELTA, IS_SCARA)
#if IS_KINEMATIC
if (!position_is_reachable(x, y)) return;
destination = current_position; // sync destination at the start
#endif
Expand Down
8 changes: 8 additions & 0 deletions Marlin/src/module/motion.h
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,14 @@ void home_if_needed(const bool keeplev=false);

return HYPOT2(rx, ry) <= sq(DELTA_PRINTABLE_RADIUS - inset + fslop);

#elif ENABLED(POLARGRAPH)

const float x1 = rx - (X_MIN_POS), x2 = (X_MAX_POS) - rx, y = ry - (Y_MAX_POS),
a = HYPOT(x1, y), b = HYPOT(x2, y);
return a < (POLARGRAPH_MAX_BELT_LEN) + 1
&& b < (POLARGRAPH_MAX_BELT_LEN) + 1
&& (a + b) > _MIN(X_BED_SIZE, Y_BED_SIZE);

#elif ENABLED(AXEL_TPARA)

const float R2 = HYPOT2(rx - TPARA_OFFSET_X, ry - TPARA_OFFSET_Y);
Expand Down
4 changes: 2 additions & 2 deletions Marlin/src/module/planner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3021,7 +3021,7 @@ bool Planner::buffer_line(const xyze_pos_t &cart, const_feedRate_t fr_mm_s, cons
#else
const feedRate_t feedrate = fr_mm_s;
#endif
delta.e = machine.e;
TERN_(HAS_EXTRUDERS, delta.e = machine.e);
if (buffer_segment(delta OPTARG(HAS_DIST_MM_ARG, cart_dist_mm), feedrate, extruder, mm)) {
position_cart = cart;
return true;
Expand Down Expand Up @@ -3126,7 +3126,7 @@ void Planner::set_position_mm(const xyze_pos_t &xyze) {
#if IS_KINEMATIC
position_cart = xyze;
inverse_kinematics(machine);
delta.e = machine.e;
TERN_(HAS_EXTRUDERS, delta.e = machine.e);
set_machine_position_mm(delta);
#else
set_machine_position_mm(machine);
Expand Down
2 changes: 2 additions & 0 deletions Marlin/src/module/planner.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@

#if ENABLED(DELTA)
#include "delta.h"
#elif ENABLED(POLARGRAPH)
#include "polargraph.h"
#endif

#if ABL_PLANAR
Expand Down
47 changes: 47 additions & 0 deletions Marlin/src/module/polargraph.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/

/**
* polargraph.cpp
*/

#include "../inc/MarlinConfig.h"

#if ENABLED(POLARGRAPH)

#include "polargraph.h"
#include "motion.h"

// For homing:
#include "planner.h"
#include "endstops.h"
#include "../lcd/marlinui.h"
#include "../MarlinCore.h"

float segments_per_second; // Initialized by settings.load()

void inverse_kinematics(const xyz_pos_t &raw) {
const float x1 = raw.x - (X_MIN_POS), x2 = (X_MAX_POS) - raw.x, y = raw.y - (Y_MAX_POS);
delta.set(HYPOT(x1, y), HYPOT(x2, y), raw.z);
}

#endif // POLARGRAPH
33 changes: 33 additions & 0 deletions Marlin/src/module/polargraph.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once

/**
* polargraph.h - Polargraph-specific functions
*/

#include "../core/types.h"
#include "../core/macros.h"

extern float segments_per_second;

void inverse_kinematics(const xyz_pos_t &raw);
Loading

0 comments on commit d3ddfa2

Please sign in to comment.