mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2026-01-04 21:57:44 -07:00
Merge 1b094d0432 into f8c6ba224f
This commit is contained in:
commit
940d2bf4a1
24 changed files with 538 additions and 115 deletions
|
|
@ -2339,22 +2339,6 @@
|
|||
|
||||
//#define FAST_BUTTON_POLLING // Poll buttons at ~1kHz on 8-bit AVR. Set to 'false' for slow polling on 32-bit.
|
||||
|
||||
// @section safety
|
||||
|
||||
/**
|
||||
* The watchdog hardware timer will do a reset and disable all outputs
|
||||
* if the firmware gets too overloaded to read the temperature sensors.
|
||||
*
|
||||
* If you find that watchdog reboot causes your AVR board to hang forever,
|
||||
* enable WATCHDOG_RESET_MANUAL to use a custom timer instead of WDTO.
|
||||
* NOTE: This method is less reliable as it can only catch hangups while
|
||||
* interrupts are enabled.
|
||||
*/
|
||||
#define USE_WATCHDOG
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
//#define WATCHDOG_RESET_MANUAL
|
||||
#endif
|
||||
|
||||
// @section lcd
|
||||
|
||||
/**
|
||||
|
|
@ -3699,6 +3683,33 @@
|
|||
|
||||
// @section cnc
|
||||
|
||||
/**
|
||||
* CNC Coordinate Systems
|
||||
*
|
||||
* Enables G53 and G54-G59.3 commands to select coordinate systems
|
||||
* and G92.1 to reset the workspace to native machine space.
|
||||
*/
|
||||
//#define CNC_COORDINATE_SYSTEMS
|
||||
|
||||
/**
|
||||
* Coordinate System Scaling
|
||||
*
|
||||
* Enable G51 to scale and G50 to cancel scaling of the coordinate system.
|
||||
* Mirroring can be achieved by using G51 with negative factors.
|
||||
*
|
||||
*/
|
||||
//#define SCALE_WORKSPACE
|
||||
|
||||
/**
|
||||
* Rotate Workspace
|
||||
*
|
||||
* Enable G68 to rotate and G69 to cancel rotation of the workspace.
|
||||
*/
|
||||
//#define ROTATE_WORKSPACE
|
||||
#if ENABLED(ROTATE_WORKSPACE) && DISABLED(DELTA)
|
||||
//#define LIMIT_ROTATION_ANGLE // Limit rotation on square beds
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Spindle & Laser control
|
||||
*
|
||||
|
|
@ -3966,6 +3977,20 @@
|
|||
|
||||
// @section safety
|
||||
|
||||
/**
|
||||
* The watchdog hardware timer will do a reset and disable all outputs
|
||||
* if the firmware gets too overloaded to read the temperature sensors.
|
||||
*
|
||||
* If you find that watchdog reboot causes your AVR board to hang forever,
|
||||
* enable WATCHDOG_RESET_MANUAL to use a custom timer instead of WDTO.
|
||||
* NOTE: This method is less reliable as it can only catch hangups while
|
||||
* interrupts are enabled.
|
||||
*/
|
||||
#define USE_WATCHDOG
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
//#define WATCHDOG_RESET_MANUAL
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Stepper Driver Anti-SNAFU Protection
|
||||
*
|
||||
|
|
@ -3975,16 +4000,6 @@
|
|||
*/
|
||||
//#define DISABLE_DRIVER_SAFE_POWER_PROTECT
|
||||
|
||||
// @section cnc
|
||||
|
||||
/**
|
||||
* CNC Coordinate Systems
|
||||
*
|
||||
* Enables G53 and G54-G59.3 commands to select coordinate systems
|
||||
* and G92.1 to reset the workspace to native machine space.
|
||||
*/
|
||||
//#define CNC_COORDINATE_SYSTEMS
|
||||
|
||||
// @section security
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -711,7 +711,7 @@ void GcodeSuite::G26() {
|
|||
#endif
|
||||
float trig_table[A_CNT];
|
||||
for (uint8_t i = 0; i < A_CNT; ++i)
|
||||
trig_table[i] = INTERSECTION_CIRCLE_RADIUS * cos(RADIANS(i * A_INT));
|
||||
trig_table[i] = INTERSECTION_CIRCLE_RADIUS * cosf(RADIANS(i * A_INT));
|
||||
|
||||
#endif // !ARC_SUPPORT
|
||||
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
|
|||
I_LOOP_CAL_PT(rad, start, steps) {
|
||||
const float a = RADIANS(210 + (360 / NPP) * (rad - 1)),
|
||||
r = dcr * 0.1;
|
||||
const xy_pos_t vec = { cos(a), sin(a) };
|
||||
const xy_pos_t vec = { cosf(a), sinf(a) };
|
||||
z_pt[CEN] += calibration_probe(vec * r, stow_after_each, probe_at_offset);
|
||||
if (isnan(z_pt[CEN])) return false;
|
||||
}
|
||||
|
|
@ -234,12 +234,12 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
|
|||
const float a = RADIANS(210 + (360 / NPP) * (rad - 1)),
|
||||
r = dcr * (1 - 0.1 * (zig_zag ? offset - circle : circle)),
|
||||
interpol = FMOD(rad, 1);
|
||||
const xy_pos_t vec = { cos(a), sin(a) };
|
||||
const xy_pos_t vec = { cosf(a), sinf(a) };
|
||||
const float z_temp = calibration_probe(vec * r, stow_after_each, probe_at_offset);
|
||||
if (isnan(z_temp)) return false;
|
||||
// split probe point to neighbouring calibration points
|
||||
z_pt[uint8_t(LROUND(rad - interpol + NPP - 1)) % NPP + 1] += z_temp * sq(cos(RADIANS(interpol * 90)));
|
||||
z_pt[uint8_t(LROUND(rad - interpol)) % NPP + 1] += z_temp * sq(sin(RADIANS(interpol * 90)));
|
||||
z_pt[uint8_t(LROUND(rad - interpol + NPP - 1)) % NPP + 1] += z_temp * sq(cosf(RADIANS(interpol * 90)));
|
||||
z_pt[uint8_t(LROUND(rad - interpol)) % NPP + 1] += z_temp * sq(sinf(RADIANS(interpol * 90)));
|
||||
}
|
||||
FLIP(zig_zag);
|
||||
}
|
||||
|
|
@ -266,7 +266,7 @@ static void reverse_kinematics_probe_points(float z_pt[NPP + 1], abc_float_t mm_
|
|||
LOOP_CAL_ALL(rad) {
|
||||
const float a = RADIANS(210 + (360 / NPP) * (rad - 1)),
|
||||
r = (rad == CEN ? 0.0f : dcr);
|
||||
pos.set(cos(a) * r, sin(a) * r, z_pt[rad]);
|
||||
pos.set(cosf(a) * r, sinf(a) * r, z_pt[rad]);
|
||||
inverse_kinematics(pos);
|
||||
mm_at_pt_axis[rad] = delta;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -195,8 +195,8 @@ void GcodeSuite::M48() {
|
|||
// Choose the next position as an offset to chosen test position
|
||||
const xy_pos_t noz_pos = test_position - probe.offset_xy;
|
||||
xy_pos_t next_pos = {
|
||||
noz_pos.x + float(cos(RADIANS(angle))) * radius,
|
||||
noz_pos.y + float(sin(RADIANS(angle))) * radius
|
||||
noz_pos.x + float(cosf(RADIANS(angle))) * radius,
|
||||
noz_pos.y + float(sinf(RADIANS(angle))) * radius
|
||||
};
|
||||
|
||||
#if ENABLED(DELTA)
|
||||
|
|
|
|||
|
|
@ -104,6 +104,27 @@ relative_t GcodeSuite::axis_relative; // Init in constructor
|
|||
xyz_pos_t GcodeSuite::coordinate_system[MAX_COORDINATE_SYSTEMS];
|
||||
#endif
|
||||
|
||||
#if ENABLED(SCALE_WORKSPACE)
|
||||
GcodeSuite::scaling_center_t GcodeSuite::scaling_center;
|
||||
GcodeSuite::scaling_factor_t GcodeSuite::scaling_factor;
|
||||
bool GcodeSuite::scaling_flag = false; // true if scaling is active
|
||||
#endif
|
||||
|
||||
#if ENABLED(ROTATE_WORKSPACE)
|
||||
float GcodeSuite::rotation_cos = 1.0f;
|
||||
float GcodeSuite::rotation_sin = 0.0f;
|
||||
float GcodeSuite::rotation_angle; // = 0.0f
|
||||
xy_pos_t GcodeSuite::rotation_center; // = { 0.0f, 0.0f }
|
||||
bool GcodeSuite::rotation_flag = false; // true if rotation is active
|
||||
|
||||
void GcodeSuite::set_rotation_angle(const float angle) {
|
||||
rotation_angle = angle;
|
||||
const float angle_rad = RADIANS(rotation_angle);
|
||||
rotation_cos = cosf(angle_rad);
|
||||
rotation_sin = sinf(angle_rad);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLED(GCODE_MACROS)
|
||||
char GcodeSuite::macros[GCODE_MACROS_SLOTS][GCODE_MACROS_SLOT_SIZE + 1] = {{ 0 }};
|
||||
#endif
|
||||
|
|
@ -160,6 +181,54 @@ int8_t GcodeSuite::get_target_e_stepper_from_command(const int8_t dval/*=-1*/) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
#if ANY(ROTATE_WORKSPACE, SCALE_WORKSPACE)
|
||||
|
||||
// Apply inverse transformations
|
||||
void GcodeSuite::inverse_workspace_transforms(xyz_pos_t &point) {
|
||||
#if ENABLED(ROTATE_WORKSPACE)
|
||||
// Inverse Rotation
|
||||
if (rotation_flag) {
|
||||
const float dx = point.x - rotation_center.x, dy = point.y - rotation_center.y;
|
||||
point.x = rotation_center.x + dx * rotation_cos - dy * (-rotation_sin);
|
||||
point.y = rotation_center.y + dx * (-rotation_sin) + dy * rotation_cos;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLED(SCALE_WORKSPACE)
|
||||
// Inverse Scaling
|
||||
if (scaling_flag) {
|
||||
point.x = scaling_center.x + (point.x - scaling_center.x) / scaling_factor.x;
|
||||
TERN_(HAS_Y_AXIS, point.y = scaling_center.y + (point.y - scaling_center.y) / scaling_factor.y);
|
||||
#if HAS_Z_AXIS
|
||||
point.z = TERN(SCALE_Z_FROM_NONZERO, scaling_center.z + (point.z - scaling_center.z), point.z) / scaling_factor.z;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Apply forward transformations
|
||||
void GcodeSuite::apply_workspace_transforms(xyz_pos_t &point) {
|
||||
#if ENABLED(SCALE_WORKSPACE)
|
||||
// Apply Scaling transformation
|
||||
if (scaling_flag) {
|
||||
point.x = scaling_center.x + (point.x - scaling_center.x) * scaling_factor.x;
|
||||
TERN_(HAS_Y_AXIS, point.y = scaling_center.y + (point.y - scaling_center.y) * scaling_factor.y);
|
||||
TERN_(HAS_Z_AXIS, point.z = scaling_center.z + (point.z - scaling_center.z) * scaling_factor.z);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLED(ROTATE_WORKSPACE)
|
||||
// Apply Rotation transformation
|
||||
if (rotation_flag) {
|
||||
const float dx = point.x - rotation_center.x, dy = point.y - rotation_center.y;
|
||||
point.x = rotation_center.x + dx * rotation_cos - dy * rotation_sin;
|
||||
point.y = rotation_center.y + dx * rotation_sin + dy * rotation_cos;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // ROTATE_WORKSPACE || SCALE_WORKSPACE
|
||||
|
||||
/**
|
||||
* Set XYZ...E destination and feedrate from the current G-Code command
|
||||
*
|
||||
|
|
@ -169,6 +238,7 @@ int8_t GcodeSuite::get_target_e_stepper_from_command(const int8_t dval/*=-1*/) {
|
|||
*/
|
||||
void GcodeSuite::get_destination_from_command() {
|
||||
xyze_bool_t seen{false};
|
||||
xyze_pos_t raw_destination;
|
||||
|
||||
#if ENABLED(CANCEL_OBJECTS)
|
||||
const bool &skip_move = cancelable.state.skipping;
|
||||
|
|
@ -176,19 +246,32 @@ void GcodeSuite::get_destination_from_command() {
|
|||
constexpr bool skip_move = false;
|
||||
#endif
|
||||
|
||||
raw_destination = current_position; // Get the current position
|
||||
|
||||
#if ANY(ROTATE_WORKSPACE, SCALE_WORKSPACE)
|
||||
// Apply inverse transformations
|
||||
if (TERN0(SCALE_WORKSPACE, scaling_flag) || TERN0(ROTATE_WORKSPACE, rotation_flag))
|
||||
inverse_workspace_transforms(raw_destination);
|
||||
#endif
|
||||
|
||||
// Get new XYZ position, whether absolute or relative
|
||||
LOOP_NUM_AXES(i) {
|
||||
if ( (seen[i] = parser.seenval(AXIS_CHAR(i))) ) {
|
||||
const float v = parser.value_axis_units((AxisEnum)i);
|
||||
if (skip_move)
|
||||
destination[i] = current_position[i];
|
||||
else
|
||||
destination[i] = axis_is_relative((AxisEnum)i) ? current_position[i] + v : LOGICAL_TO_NATIVE(v, i);
|
||||
if (!skip_move) {
|
||||
const float v = parser.value_axis_units((AxisEnum)i);
|
||||
raw_destination[i] = axis_is_relative((AxisEnum)i) ? raw_destination[i] + v : LOGICAL_TO_NATIVE(v, i);
|
||||
}
|
||||
}
|
||||
else
|
||||
destination[i] = current_position[i];
|
||||
}
|
||||
|
||||
destination = raw_destination; // Get the final machine destination
|
||||
|
||||
#if ANY(SCALE_WORKSPACE, ROTATE_WORKSPACE)
|
||||
// Apply forward transformations
|
||||
if (TERN0(SCALE_WORKSPACE, scaling_flag) || TERN0(ROTATE_WORKSPACE, rotation_flag))
|
||||
apply_workspace_transforms(destination);
|
||||
#endif
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
// Get new E position, whether absolute or relative
|
||||
if ( (seen.e = parser.seenval('E')) ) {
|
||||
|
|
@ -217,8 +300,8 @@ void GcodeSuite::get_destination_from_command() {
|
|||
print_job_timer.incFilamentUsed(destination.e - current_position.e);
|
||||
#endif
|
||||
|
||||
// Get ABCDHI mixing factors
|
||||
#if ALL(MIXING_EXTRUDER, DIRECT_MIXING_IN_G1)
|
||||
// Get ABCDHI mixing factors
|
||||
M165();
|
||||
#endif
|
||||
|
||||
|
|
@ -440,6 +523,11 @@ void GcodeSuite::process_parsed_command(bool no_ok/*=false*/) {
|
|||
case 42: G42(); break; // G42: Coordinated move to a mesh point
|
||||
#endif
|
||||
|
||||
#if ENABLED(SCALE_WORKSPACE)
|
||||
case 50: G50(); break; // G50: Cancel Workspace Scaling
|
||||
case 51: G51(); break; // G51: Set Workspace Scaling
|
||||
#endif
|
||||
|
||||
#if ENABLED(CNC_COORDINATE_SYSTEMS)
|
||||
case 53: G53(); break; // G53: (prefix) Apply native workspace
|
||||
case 54: G54(); break; // G54: Switch to Workspace 1
|
||||
|
|
@ -455,6 +543,11 @@ void GcodeSuite::process_parsed_command(bool no_ok/*=false*/) {
|
|||
case 61: G61(); break; // G61: Apply/restore saved coordinates.
|
||||
#endif
|
||||
|
||||
#if ENABLED(ROTATE_WORKSPACE)
|
||||
case 68: G68(); break; // G68: Set Workspace Rotation
|
||||
case 69: G69(); break; // G69: Cancel Workspace Rotation
|
||||
#endif
|
||||
|
||||
#if ALL(PTC_PROBE, PTC_BED)
|
||||
case 76: G76(); break; // G76: Calibrate first layer compensation values
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -64,8 +64,12 @@
|
|||
* G35 - Read bed corners to help adjust bed screws: T<screw_thread> (Requires ASSISTED_TRAMMING)
|
||||
* G38 - Probe in any direction using the Z_MIN_PROBE (Requires G38_PROBE_TARGET)
|
||||
* G42 - Coordinated move to a mesh point (Requires MESH_BED_LEVELING, AUTO_BED_LEVELING_BLINEAR, or AUTO_BED_LEVELING_UBL)
|
||||
* G50 - Cancel Workspace Scaling (Requires SCALE_WORKSPACE)
|
||||
* G51 - Set Workspace Scaling (Requires SCALE_WORKSPACE)
|
||||
* G60 - Save current position. (Requires SAVED_POSITIONS)
|
||||
* G61 - Apply/Restore saved coordinates. (Requires SAVED_POSITIONS)
|
||||
* G68 - Set Workspace Rotation (Requires ROTATE_WORKSPACE)
|
||||
* G69 - Cancel Workspace Rotation (Requires ROTATE_WORKSPACE)
|
||||
* G76 - Calibrate first layer temperature offsets. (Requires PTC_PROBE and PTC_BED)
|
||||
* G80 - Cancel current motion mode (Requires GCODE_MOTION_MODES)
|
||||
* G90 - Use Absolute Coordinates
|
||||
|
|
@ -438,6 +442,50 @@ public:
|
|||
static bool select_coordinate_system(const int8_t _new);
|
||||
#endif
|
||||
|
||||
#if ANY(ROTATE_WORKSPACE, SCALE_WORKSPACE)
|
||||
static void inverse_workspace_transforms(xyz_pos_t &point);
|
||||
static void apply_workspace_transforms(xyz_pos_t &point);
|
||||
|
||||
#if ENABLED(SCALE_WORKSPACE)
|
||||
#if HAS_Z_AXIS && Z_MIN_POS != 0
|
||||
#define SCALE_Z_FROM_NONZERO 1
|
||||
#endif
|
||||
typedef struct ScalingCenter {
|
||||
float x = 0.0f;
|
||||
#if HAS_Y_AXIS
|
||||
float y = 0.0f;
|
||||
#endif
|
||||
#if SCALE_Z_FROM_NONZERO
|
||||
float z = 0.0f;
|
||||
#elif HAS_Z_AXIS
|
||||
static constexpr float z = 0.0f;
|
||||
#endif
|
||||
void reset() { x = TERN_(HAS_Y_AXIS, y =) TERN_(SCALE_Z_FROM_NONZERO, z =) 0.0f; }
|
||||
} scaling_center_t;
|
||||
typedef struct ScalingFactor {
|
||||
float x = 1.0f;
|
||||
#if HAS_Y_AXIS
|
||||
float y = 1.0f;
|
||||
#endif
|
||||
#if HAS_Z_AXIS
|
||||
float z = 1.0f;
|
||||
#endif
|
||||
void reset() { x = TERN_(HAS_Y_AXIS, y =) TERN_(HAS_Z_AXIS, z =) 1.0f; }
|
||||
} scaling_factor_t;
|
||||
|
||||
static scaling_center_t scaling_center;
|
||||
static scaling_factor_t scaling_factor;
|
||||
static bool scaling_flag;
|
||||
#endif
|
||||
|
||||
#if ENABLED(ROTATE_WORKSPACE)
|
||||
static float rotation_angle;
|
||||
static xy_pos_t rotation_center;
|
||||
static bool rotation_flag;
|
||||
static void set_rotation_angle(const float angle);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static millis_t previous_move_ms, max_inactive_time;
|
||||
FORCE_INLINE static bool stepper_max_timed_out(const millis_t ms=millis()) {
|
||||
return max_inactive_time && ELAPSED(ms, previous_move_ms, max_inactive_time);
|
||||
|
|
@ -604,11 +652,6 @@ private:
|
|||
static void G34();
|
||||
#endif
|
||||
|
||||
#if ENABLED(Z_STEPPER_AUTO_ALIGN)
|
||||
static void M422();
|
||||
static void M422_report(const bool forReplay=true);
|
||||
#endif
|
||||
|
||||
#if ENABLED(ASSISTED_TRAMMING)
|
||||
static void G35();
|
||||
#endif
|
||||
|
|
@ -621,6 +664,11 @@ private:
|
|||
static void G42();
|
||||
#endif
|
||||
|
||||
#if ENABLED(SCALE_WORKSPACE)
|
||||
static void G50();
|
||||
static void G51();
|
||||
#endif
|
||||
|
||||
#if ENABLED(CNC_COORDINATE_SYSTEMS)
|
||||
static void G53();
|
||||
static void G54();
|
||||
|
|
@ -631,15 +679,22 @@ private:
|
|||
static void G59();
|
||||
#endif
|
||||
|
||||
#if ALL(PTC_PROBE, PTC_BED)
|
||||
static void G76();
|
||||
#endif
|
||||
|
||||
#if SAVED_POSITIONS
|
||||
static void G60();
|
||||
static void G61(int8_t slot=-1);
|
||||
#endif
|
||||
|
||||
#if ENABLED(ROTATE_WORKSPACE)
|
||||
static void G68();
|
||||
static void G69();
|
||||
static float rotation_cos;
|
||||
static float rotation_sin;
|
||||
#endif
|
||||
|
||||
#if ALL(PTC_PROBE, PTC_BED)
|
||||
static void G76();
|
||||
#endif
|
||||
|
||||
#if ENABLED(GCODE_MOTION_MODES)
|
||||
static void G80();
|
||||
#endif
|
||||
|
|
@ -790,14 +845,9 @@ private:
|
|||
#endif
|
||||
|
||||
static void M108();
|
||||
static void M112();
|
||||
static void M410();
|
||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||
static void M876();
|
||||
#endif
|
||||
|
||||
static void M110();
|
||||
static void M111();
|
||||
static void M112();
|
||||
|
||||
#if ENABLED(HOST_KEEPALIVE_FEATURE)
|
||||
static void M113();
|
||||
|
|
@ -1082,11 +1132,18 @@ private:
|
|||
static void M407();
|
||||
#endif
|
||||
|
||||
static void M410();
|
||||
|
||||
#if HAS_FILAMENT_SENSOR
|
||||
static void M412();
|
||||
static void M412_report(const bool forReplay=true);
|
||||
#endif
|
||||
|
||||
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||
static void M413();
|
||||
static void M413_report(const bool forReplay=true);
|
||||
#endif
|
||||
|
||||
#if HAS_MULTI_LANGUAGE
|
||||
static void M414();
|
||||
static void M414_report(const bool forReplay=true);
|
||||
|
|
@ -1098,6 +1155,16 @@ private:
|
|||
static void M421();
|
||||
#endif
|
||||
|
||||
#if ENABLED(Z_STEPPER_AUTO_ALIGN)
|
||||
static void M422();
|
||||
static void M422_report(const bool forReplay=true);
|
||||
#endif
|
||||
|
||||
#if ENABLED(X_AXIS_TWIST_COMPENSATION)
|
||||
static void M423();
|
||||
static void M423_report(const bool forReplay=true);
|
||||
#endif
|
||||
|
||||
#if ENABLED(BACKLASH_GCODE)
|
||||
static void M425();
|
||||
static void M425_report(const bool forReplay=true);
|
||||
|
|
@ -1230,6 +1297,11 @@ private:
|
|||
static void MMU3_report(const bool forReplay=true);
|
||||
#endif
|
||||
|
||||
#if ENABLED(CONTROLLER_FAN_EDITABLE)
|
||||
static void M710();
|
||||
static void M710_report(const bool forReplay=true);
|
||||
#endif
|
||||
|
||||
#if ENABLED(GCODE_REPEAT_MARKERS)
|
||||
static void M808();
|
||||
#endif
|
||||
|
|
@ -1267,6 +1339,10 @@ private:
|
|||
static void M871();
|
||||
#endif
|
||||
|
||||
#if HAS_GCODE_M876
|
||||
static void M876();
|
||||
#endif
|
||||
|
||||
#if HAS_LIN_ADVANCE_K
|
||||
static void M900();
|
||||
static void M900_report(const bool forReplay=true);
|
||||
|
|
@ -1337,16 +1413,9 @@ private:
|
|||
static void M999();
|
||||
|
||||
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||
static void M413();
|
||||
static void M413_report(const bool forReplay=true);
|
||||
static void M1000();
|
||||
#endif
|
||||
|
||||
#if ENABLED(X_AXIS_TWIST_COMPENSATION)
|
||||
static void M423();
|
||||
static void M423_report(const bool forReplay=true);
|
||||
#endif
|
||||
|
||||
#if HAS_MEDIA
|
||||
static void M1001();
|
||||
#endif
|
||||
|
|
@ -1371,11 +1440,6 @@ private:
|
|||
static void M7219();
|
||||
#endif
|
||||
|
||||
#if ENABLED(CONTROLLER_FAN_EDITABLE)
|
||||
static void M710();
|
||||
static void M710_report(const bool forReplay=true);
|
||||
#endif
|
||||
|
||||
static void T(const int8_t tool_index) IF_DISABLED(HAS_TOOLCHANGE, { UNUSED(tool_index); });
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -37,8 +37,13 @@ inline void report_workspace_plane() {
|
|||
}
|
||||
|
||||
inline void set_workspace_plane(const GcodeSuite::WorkspacePlane plane) {
|
||||
gcode.workspace_plane = plane;
|
||||
if (DEBUGGING(INFO)) report_workspace_plane();
|
||||
if (TERN0(ROTATE_WORKSPACE, !NEAR_ZERO(gcode.rotation_angle))) {
|
||||
SERIAL_ECHOLNPGM("Workspace plane cannnot change while using workspace rotation!");
|
||||
}
|
||||
else {
|
||||
gcode.workspace_plane = plane;
|
||||
if (DEBUGGING(INFO)) report_workspace_plane();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
149
Marlin/src/gcode/geometry/G50_G51.cpp
Normal file
149
Marlin/src/gcode/geometry/G50_G51.cpp
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2025 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if ENABLED(SCALE_WORKSPACE)
|
||||
|
||||
#include "../gcode.h"
|
||||
#include "../../module/motion.h"
|
||||
|
||||
/**
|
||||
* G50: Cancel Workspace Scaling
|
||||
*/
|
||||
void GcodeSuite::G50() {
|
||||
scaling_factor.reset();
|
||||
scaling_center.reset();
|
||||
SERIAL_ECHO_MSG("G50: Workspace scaling canceled");
|
||||
scaling_flag = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* G51: Set Workspace Scaling
|
||||
*
|
||||
* Scale the current workspace coordinate system.
|
||||
*
|
||||
* Parameters:
|
||||
* X<linear> X coordinate of the scaling center
|
||||
* Y<linear> Y coordinate of the scaling center
|
||||
* Z<linear> Z coordinate of the scaling center
|
||||
* I<float> scaling factor for X axis
|
||||
* J<float> scaling factor for Y axis
|
||||
* K<float> scaling factor for Z axis
|
||||
* P<float> scaling factor
|
||||
* C<bool> Use current position for axes (X, Y, Z)
|
||||
*/
|
||||
void GcodeSuite::G51() {
|
||||
bool use_current_pos = parser.seen('C'); // Check if 'C' parameter is present
|
||||
|
||||
if (parser.seenval('P')) {
|
||||
const float sf = parser.value_float();
|
||||
scaling_factor.x = sf;
|
||||
TERN_(HAS_Y_AXIS, scaling_factor.y = sf);
|
||||
TERN_(HAS_Z_AXIS, scaling_factor.z = sf);
|
||||
SERIAL_ECHO_MSG("G51: Workspace scaling set to: ", sf);
|
||||
}
|
||||
else {
|
||||
if (parser.seenval('I')) scaling_factor.x = parser.value_float();
|
||||
#if HAS_Y_AXIS
|
||||
if (parser.seenval('J')) scaling_factor.y = parser.value_float();
|
||||
#endif
|
||||
#if HAS_Z_AXIS
|
||||
if (parser.seenval('K')) scaling_factor.z = parser.value_float();
|
||||
#endif
|
||||
|
||||
SERIAL_ECHO_START();
|
||||
SERIAL_ECHOLNPGM_P(
|
||||
PSTR("G51: Workspace scaling set to: X"), scaling_factor.x
|
||||
#if HAS_Y_AXIS
|
||||
, SP_Y_STR, scaling_factor.y
|
||||
#endif
|
||||
#if HAS_Z_AXIS
|
||||
, SP_Z_STR, scaling_factor.z
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
rotation_center.x = X_CENTER;
|
||||
TERN_(HAS_Y_AXIS, rotation_center.y = Y_CENTER);
|
||||
|
||||
// X-axis scaling
|
||||
const bool seenX = parser.seen('X'), hasX = seenX && parser.has_value();
|
||||
if (use_current_pos && hasX) {
|
||||
SERIAL_ECHO_MSG("?(X) cannot have a value when used with 'C'.");
|
||||
return;
|
||||
}
|
||||
scaling_center.x = (
|
||||
(use_current_pos && seenX)
|
||||
? current_position.x
|
||||
: hasX
|
||||
? LOGICAL_TO_NATIVE(parser.value_axis_units(X_AXIS), X_AXIS)
|
||||
: rotation_center.x
|
||||
);
|
||||
|
||||
// Y-axis scaling
|
||||
#if HAS_Y_AXIS
|
||||
const bool seenY = parser.seen('Y'), hasY = seenY && parser.has_value();
|
||||
if (use_current_pos && hasY) {
|
||||
SERIAL_ECHO_MSG("?(Y) cannot have a value when used with 'C'.");
|
||||
return;
|
||||
}
|
||||
scaling_center.y = (
|
||||
(use_current_pos && seenY)
|
||||
? current_position.y
|
||||
: hasY
|
||||
? LOGICAL_TO_NATIVE(parser.value_axis_units(Y_AXIS), Y_AXIS)
|
||||
: rotation_center.y
|
||||
);
|
||||
#endif
|
||||
|
||||
// Z-axis scaling
|
||||
#if SCALE_Z_FROM_NONZERO
|
||||
const bool seenZ = parser.seen('Z'), hasZ = seenZ && parser.has_value();
|
||||
if (use_current_pos && hasZ) {
|
||||
SERIAL_ECHO_MSG("?(Z) cannot have a value when used with 'C'.");
|
||||
return;
|
||||
}
|
||||
scaling_center.z = (
|
||||
(use_current_pos && seenZ)
|
||||
? current_position.z
|
||||
: hasZ
|
||||
? LOGICAL_TO_NATIVE(parser.value_axis_units(Z_AXIS), Z_AXIS)
|
||||
: 0.0f
|
||||
);
|
||||
#endif
|
||||
|
||||
SERIAL_ECHO_START();
|
||||
SERIAL_ECHOLNPGM_P(
|
||||
PSTR("Workspace scaling center X"), scaling_center.x
|
||||
#if HAS_Y_AXIS
|
||||
, SP_Y_STR, scaling_center.y
|
||||
#endif
|
||||
#if HAS_Z_AXIS
|
||||
, SP_Z_STR, scaling_center.z
|
||||
#endif
|
||||
);
|
||||
|
||||
scaling_flag = true; // Set flag to true
|
||||
}
|
||||
|
||||
#endif // SCALE_WORKSPACE
|
||||
|
|
@ -33,6 +33,10 @@
|
|||
*/
|
||||
bool GcodeSuite::select_coordinate_system(const int8_t _new) {
|
||||
if (active_coordinate_system == _new) return false;
|
||||
if (TERN0(ROTATE_WORKSPACE, gcode.rotation_angle)) {
|
||||
SERIAL_ECHOLNPGM("Cannot change workspace while rotation is active!");
|
||||
return false;
|
||||
}
|
||||
active_coordinate_system = _new;
|
||||
xyz_float_t new_offset{0};
|
||||
if (WITHIN(_new, 0, MAX_COORDINATE_SYSTEMS - 1))
|
||||
|
|
|
|||
88
Marlin/src/gcode/geometry/G68_G69.cpp
Normal file
88
Marlin/src/gcode/geometry/G68_G69.cpp
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2025 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if ENABLED(ROTATE_WORKSPACE)
|
||||
|
||||
#include "../gcode.h"
|
||||
#include "../../module/motion.h"
|
||||
|
||||
//#define USE_45DEG_INCREMENTS // Allow 45-degree increments on square beds
|
||||
|
||||
/**
|
||||
* G68: Set Workspace Rotation
|
||||
*
|
||||
* Set the rotation (about Z axis) for the current workspace (begins at 0).
|
||||
*
|
||||
* Parameters:
|
||||
* X<linear> X coordinate of the rotation center for the current workspace
|
||||
* Y<linear> Y coordinate of the rotation center for the current workspace
|
||||
* R<float> Rotation angle in degrees (Required)
|
||||
*
|
||||
* Example:
|
||||
* G68 R45 ; Rotate active workspace by 45° counter-clockwise (when viewed from positive Z)
|
||||
* G68 R-30 ; Rotate active workspace by -30°
|
||||
* G68 R180 ; Rotate active workspace by 180°
|
||||
*
|
||||
* NOTES:
|
||||
* - Only rotation is set. No translation/offset is changed.
|
||||
* - All subsequent moves are rotated by the specified angle.
|
||||
* - It is an error to change workspace or working plane while workspace rotation is active
|
||||
* (https://forums.autodesk.com/t5/fusion-manufacture-forum/probing-and-updating-wcs-for-angle/td-p/9487027 ,
|
||||
* https://www.machsupport.com/forum/index.php?topic=43012)
|
||||
*/
|
||||
void GcodeSuite::G68() {
|
||||
if (!parser.seenval('R')) {
|
||||
SERIAL_ECHO_MSG("?(R)otation angle is required.");
|
||||
return;
|
||||
}
|
||||
const float input_deg = parser.value_float();
|
||||
|
||||
#if ENABLED(LIMIT_ROTATION_ANGLE)
|
||||
// Check for a valid input angle
|
||||
if ((ABS(input_deg) % TERN(USE_45DEG_INCREMENTS, 45, 90)) != 0) {
|
||||
SERIAL_ECHO_MSG("?(R)otation must be a multiple of " TERN(USE_45DEG_INCREMENTS, "45", "90") ".");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
gcode.set_rotation_angle(input_deg);
|
||||
SERIAL_ECHO_MSG("G68: Rotation angle set to ", input_deg, " degrees.");
|
||||
|
||||
// Assume the object rotates around the bed center
|
||||
rotation_center.x = X_CENTER;
|
||||
TERN_(HAS_Y_AXIS, rotation_center.y = Y_CENTER);
|
||||
|
||||
rotation_flag = true; // Set flag to true
|
||||
}
|
||||
|
||||
/**
|
||||
* G69: Cancel Workspace Rotation
|
||||
*/
|
||||
void GcodeSuite::G69() {
|
||||
gcode.set_rotation_angle(0.0f);
|
||||
SERIAL_ECHO_MSG("G68: Workspace rotation canceled");
|
||||
rotation_flag = false;
|
||||
}
|
||||
|
||||
#endif // ROTATE_WORKSPACE
|
||||
|
|
@ -39,8 +39,6 @@
|
|||
#include "../../lcd/sovol_rts/sovol_rts.h"
|
||||
#endif
|
||||
|
||||
extern xyze_pos_t destination;
|
||||
|
||||
#if ENABLED(VARIABLE_G0_FEEDRATE)
|
||||
feedRate_t fast_move_feedrate = MMM_TO_MMS(G0_FEEDRATE);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -342,7 +342,7 @@ void plan_arc(
|
|||
// Compute exact location by applying transformation matrix from initial radius vector(=-offset).
|
||||
// To reduce stuttering, the sin and cos could be computed at different times.
|
||||
// For now, compute both at the same time.
|
||||
const float Ti = i * theta_per_segment, cos_Ti = cos(Ti), sin_Ti = sin(Ti);
|
||||
const float Ti = i * theta_per_segment, cos_Ti = cosf(Ti), sin_Ti = sinf(Ti);
|
||||
rvec.a = -offset[0] * cos_Ti + offset[1] * sin_Ti;
|
||||
rvec.b = -offset[0] * sin_Ti - offset[1] * cos_Ti;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3265,8 +3265,8 @@
|
|||
#define SKEW_FACTOR_MIN -1
|
||||
#define SKEW_FACTOR_MAX 1
|
||||
|
||||
#define _GET_SIDE(a,b,c) (SQRT(2*sq(a)+2*sq(b)-4*sq(c))*0.5)
|
||||
#define _SKEW_SIDE(a,b,c) tan(M_PI*0.5-acos((sq(a)-sq(b)-sq(c))/(2*c*b)))
|
||||
#define _GET_SIDE(a,b,c) (SQRT(2*sq(a)+2*sq(b)-4*sq(c))*0.5f)
|
||||
#define _SKEW_SIDE(a,b,c) tanf(M_PI*0.5-acosf((sq(a)-sq(b)-sq(c))/(2*c*b)))
|
||||
#define _SKEW_FACTOR(a,b,c) _SKEW_SIDE(float(a),_GET_SIDE(float(a),float(b),float(c)),float(c))
|
||||
|
||||
#ifndef XY_SKEW_FACTOR
|
||||
|
|
|
|||
|
|
@ -3765,6 +3765,10 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive."
|
|||
#error "CNC_COORDINATE_SYSTEMS is incompatible with NO_WORKSPACE_OFFSETS."
|
||||
#endif
|
||||
|
||||
#if ENABLED(ROTATE_WORKSPACE) && !HAS_Y_AXIS
|
||||
#error "ROTATE_WORKSPACE requires a machine with XY axes."
|
||||
#endif
|
||||
|
||||
#if !BLOCK_BUFFER_SIZE
|
||||
#error "BLOCK_BUFFER_SIZE must be non-zero."
|
||||
#elif BLOCK_BUFFER_SIZE > 64
|
||||
|
|
|
|||
|
|
@ -66,27 +66,27 @@ namespace FTDI {
|
|||
// Paint upper-right quadrant
|
||||
cmd.cmd(BEGIN(EDGE_STRIP_A));
|
||||
cmd.cmd(VERTEX2F(cx, cy));
|
||||
cmd.cmd(VERTEX2F(cx + ro*sin(a1) + 16,cy - ro*cos(a1) + 8));
|
||||
cmd.cmd(VERTEX2F(cx + ro * sinf(a1) + 16, cy - ro * cosf(a1) + 8));
|
||||
|
||||
// Paint lower-right quadrant
|
||||
if (a > M_PI/2) {
|
||||
cmd.cmd(BEGIN(EDGE_STRIP_R));
|
||||
cmd.cmd(VERTEX2F(cx, cy));
|
||||
cmd.cmd(VERTEX2F(cx + ro*cos(a2),cy + ro*sin(a2) + 16));
|
||||
cmd.cmd(VERTEX2F(cx + ro * cosf(a2), cy + ro * sinf(a2) + 16));
|
||||
}
|
||||
|
||||
// Paint lower-left quadrant
|
||||
if (a > M_PI) {
|
||||
cmd.cmd(BEGIN(EDGE_STRIP_B));
|
||||
cmd.cmd(VERTEX2F(cx, cy));
|
||||
cmd.cmd(VERTEX2F(cx - ro*sin(a3) - 8,cy + ro*cos(a3)));
|
||||
cmd.cmd(VERTEX2F(cx - ro * sinf(a3) - 8, cy + ro * cosf(a3)));
|
||||
}
|
||||
|
||||
// Paint upper-left quadrant
|
||||
if (a > 1.5*M_PI) {
|
||||
cmd.cmd(BEGIN(EDGE_STRIP_L));
|
||||
cmd.cmd(VERTEX2F(cx, cy));
|
||||
cmd.cmd(VERTEX2F(cx - ro*cos(a4),cy - ro*sin(a4)));
|
||||
cmd.cmd(VERTEX2F(cx - ro * cosf(a4), cy - ro * sinf(a4)));
|
||||
}
|
||||
cmd.cmd(RESTORE_CONTEXT());
|
||||
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ void _man_probe_pt(const xy_pos_t &xy) {
|
|||
float dcr = PRINTABLE_RADIUS - PROBING_MARGIN;
|
||||
TERN_(HAS_PROBE_XY_OFFSET, dcr -= HYPOT(probe.offset_xy.x, probe.offset_xy.y));
|
||||
TERN_(HAS_DELTA_SENSORLESS_PROBING, dcr *= sensorless_radius_factor);
|
||||
xy_pos_t tower_vec = { cos(RADIANS(a)), sin(RADIANS(a)) };
|
||||
xy_pos_t tower_vec = { cosf(RADIANS(a)), sinf(RADIANS(a)) };
|
||||
_man_probe_pt(tower_vec * dcr);
|
||||
}
|
||||
void _goto_tower_x() { _goto_tower_a(210); }
|
||||
|
|
|
|||
|
|
@ -143,8 +143,8 @@ Nozzle nozzle;
|
|||
for (uint8_t s = 0; s < strokes; ++s)
|
||||
for (uint8_t i = 0; i < NOZZLE_CLEAN_CIRCLE_FN; ++i)
|
||||
do_blocking_move_to_xy(
|
||||
middle.x + sin((RADIANS(360) / NOZZLE_CLEAN_CIRCLE_FN) * i) * radius,
|
||||
middle.y + cos((RADIANS(360) / NOZZLE_CLEAN_CIRCLE_FN) * i) * radius
|
||||
middle.x + sinf((RADIANS(360) / NOZZLE_CLEAN_CIRCLE_FN) * i) * radius,
|
||||
middle.y + cosf((RADIANS(360) / NOZZLE_CLEAN_CIRCLE_FN) * i) * radius
|
||||
);
|
||||
|
||||
// Let's be safe
|
||||
|
|
|
|||
|
|
@ -75,12 +75,12 @@ void refresh_delta_clip_start_height() {
|
|||
*/
|
||||
void recalc_delta_settings() {
|
||||
constexpr abc_float_t trt = DELTA_RADIUS_TRIM_TOWER;
|
||||
delta_tower[A_AXIS].set(cos(RADIANS(210 + delta_tower_angle_trim.a)) * (delta_radius + trt.a), // front left tower
|
||||
sin(RADIANS(210 + delta_tower_angle_trim.a)) * (delta_radius + trt.a));
|
||||
delta_tower[B_AXIS].set(cos(RADIANS(330 + delta_tower_angle_trim.b)) * (delta_radius + trt.b), // front right tower
|
||||
sin(RADIANS(330 + delta_tower_angle_trim.b)) * (delta_radius + trt.b));
|
||||
delta_tower[C_AXIS].set(cos(RADIANS( 90 + delta_tower_angle_trim.c)) * (delta_radius + trt.c), // back middle tower
|
||||
sin(RADIANS( 90 + delta_tower_angle_trim.c)) * (delta_radius + trt.c));
|
||||
delta_tower[A_AXIS].set(cosf(RADIANS(210 + delta_tower_angle_trim.a)) * (delta_radius + trt.a), // front left tower
|
||||
sinf(RADIANS(210 + delta_tower_angle_trim.a)) * (delta_radius + trt.a));
|
||||
delta_tower[B_AXIS].set(cosf(RADIANS(330 + delta_tower_angle_trim.b)) * (delta_radius + trt.b), // front right tower
|
||||
sinf(RADIANS(330 + delta_tower_angle_trim.b)) * (delta_radius + trt.b));
|
||||
delta_tower[C_AXIS].set(cosf(RADIANS( 90 + delta_tower_angle_trim.c)) * (delta_radius + trt.c), // back middle tower
|
||||
sinf(RADIANS( 90 + delta_tower_angle_trim.c)) * (delta_radius + trt.c));
|
||||
delta_diagonal_rod_2_tower.set(sq(delta_diagonal_rod + delta_diagonal_rod_trim.a),
|
||||
sq(delta_diagonal_rod + delta_diagonal_rod_trim.b),
|
||||
sq(delta_diagonal_rod + delta_diagonal_rod_trim.c));
|
||||
|
|
|
|||
|
|
@ -774,16 +774,18 @@ void get_cartesian_from_steppers() {
|
|||
forward_kinematics(planner.get_axis_position_mm(X_AXIS), planner.get_axis_position_degrees(B_AXIS));
|
||||
cartes.z = planner.get_axis_position_mm(Z_AXIS);
|
||||
#else
|
||||
NUM_AXIS_CODE(
|
||||
cartes.x = planner.get_axis_position_mm(X_AXIS),
|
||||
cartes.y = planner.get_axis_position_mm(Y_AXIS),
|
||||
cartes.z = planner.get_axis_position_mm(Z_AXIS),
|
||||
cartes.i = planner.get_axis_position_mm(I_AXIS),
|
||||
cartes.j = planner.get_axis_position_mm(J_AXIS),
|
||||
cartes.k = planner.get_axis_position_mm(K_AXIS),
|
||||
cartes.u = planner.get_axis_position_mm(U_AXIS),
|
||||
cartes.v = planner.get_axis_position_mm(V_AXIS),
|
||||
cartes.w = planner.get_axis_position_mm(W_AXIS)
|
||||
cartes.set(
|
||||
NUM_AXIS_LIST(
|
||||
planner.get_axis_position_mm(X_AXIS),
|
||||
planner.get_axis_position_mm(Y_AXIS),
|
||||
planner.get_axis_position_mm(Z_AXIS),
|
||||
planner.get_axis_position_mm(I_AXIS),
|
||||
planner.get_axis_position_mm(J_AXIS),
|
||||
planner.get_axis_position_mm(K_AXIS),
|
||||
planner.get_axis_position_mm(U_AXIS),
|
||||
planner.get_axis_position_mm(V_AXIS),
|
||||
planner.get_axis_position_mm(W_AXIS)
|
||||
)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2591,9 +2591,9 @@ bool Planner::_populate_block(
|
|||
* constexpr float c = 1.00751495f; // Correction factor to center error around 0
|
||||
* for (int i = 0; i < jd_lut_count - 1; ++i) {
|
||||
* const float x0 = (sq(i) - 1) / sq(i),
|
||||
* y0 = acos(x0) * (i == 0 ? 1 : c),
|
||||
* y0 = acosf(x0) * (i == 0 ? 1 : c),
|
||||
* x1 = i < jd_lut_count - 1 ? 0.5 * x0 + 0.5 : 0.999999f,
|
||||
* y1 = acos(x1) * (i < jd_lut_count - 1 ? c : 1);
|
||||
* y1 = acosf(x1) * (i < jd_lut_count - 1 ? c : 1);
|
||||
* jd_lut_k[i] = (y0 - y1) / (x0 - x1);
|
||||
* jd_lut_b[i] = (y1 * x0 - y0 * x1) / (x0 - x1);
|
||||
* }
|
||||
|
|
@ -2601,7 +2601,7 @@ bool Planner::_populate_block(
|
|||
* // Compute correction factor (Set c to 1.0f first!)
|
||||
* float min = INFINITY, max = -min;
|
||||
* for (float t = 0; t <= 1; t += 0.0003f) {
|
||||
* const float e = acos(t) / approx(t);
|
||||
* const float e = acosf(t) / approx(t);
|
||||
* if (isfinite(e)) {
|
||||
* if (e < min) min = e;
|
||||
* if (e > max) max = e;
|
||||
|
|
|
|||
|
|
@ -58,8 +58,7 @@ void forward_kinematics(const float r, const float theta) {
|
|||
const float absTheta = absoluteAngle(theta);
|
||||
float radius = r;
|
||||
if (polar_center_offset > 0.0) radius = SQRT( ABS( sq(r) - sq(-polar_center_offset) ) );
|
||||
cartes.x = cos(RADIANS(absTheta))*radius;
|
||||
cartes.y = sin(RADIANS(absTheta))*radius;
|
||||
cartes.set(cosf(RADIANS(absTheta)) * radius, sinf(RADIANS(absTheta)) * radius);
|
||||
}
|
||||
|
||||
void inverse_kinematics(const xyz_pos_t &raw) {
|
||||
|
|
|
|||
|
|
@ -48,10 +48,10 @@ float segments_per_second = DEFAULT_SEGMENTS_PER_SECOND;
|
|||
* Integrated into Marlin and slightly restructured by Joachim Cerny.
|
||||
*/
|
||||
void forward_kinematics(const float a, const float b) {
|
||||
const float a_sin = sin(RADIANS(a)) * L1,
|
||||
a_cos = cos(RADIANS(a)) * L1,
|
||||
b_sin = sin(RADIANS(SUM_TERN(MP_SCARA, b, a))) * L2,
|
||||
b_cos = cos(RADIANS(SUM_TERN(MP_SCARA, b, a))) * L2;
|
||||
const float a_sin = sinf(RADIANS(a)) * L1,
|
||||
a_cos = cosf(RADIANS(a)) * L1,
|
||||
b_sin = sinf(RADIANS(SUM_TERN(MP_SCARA, b, a))) * L2,
|
||||
b_cos = cosf(RADIANS(SUM_TERN(MP_SCARA, b, a))) * L2;
|
||||
|
||||
cartes.x = a_cos + b_cos + scara_offset.x; // theta
|
||||
cartes.y = a_sin + b_sin + scara_offset.y; // phi
|
||||
|
|
@ -273,10 +273,10 @@ float segments_per_second = DEFAULT_SEGMENTS_PER_SECOND;
|
|||
// Convert ABC inputs in degrees to XYZ outputs in mm
|
||||
void forward_kinematics(const float a, const float b, const float c) {
|
||||
const float w = c - b,
|
||||
r = L1 * cos(RADIANS(b)) + L2 * sin(RADIANS(w - (90 - b))),
|
||||
x = r * cos(RADIANS(a)),
|
||||
y = r * sin(RADIANS(a)),
|
||||
rho2 = L1_2 + L2_2 - 2.0f * L1 * L2 * cos(RADIANS(w));
|
||||
r = L1 * cosf(RADIANS(b)) + L2 * sinf(RADIANS(w - (90 - b))),
|
||||
x = r * cosf(RADIANS(a)),
|
||||
y = r * sinf(RADIANS(a)),
|
||||
rho2 = L1_2 + L2_2 - 2.0f * L1 * L2 * cosf(RADIANS(w));
|
||||
|
||||
const xyz_pos_t calculated_fk = xyz_pos_t({ x, y, SQRT(rho2 - sq(x) - sq(y)) }) ;
|
||||
cartes = calculated_fk + robot_shoulder_offset + tool_offset - robot_workspace_offset;
|
||||
|
|
@ -380,8 +380,8 @@ float segments_per_second = DEFAULT_SEGMENTS_PER_SECOND;
|
|||
GAMMA = ATAN2(SG, CG), // Method 2
|
||||
|
||||
// Angle of Shoulder Joint, elevation angle measured from horizontal plane XY (r+)
|
||||
//PHI = asin(tpos.z/RHO) + asin(L2 * sin(GAMMA) / RHO), // Method 1
|
||||
PHI = ATAN2(tpos.z, RXY) + ATAN2(K2, K1), // Method 2
|
||||
//PHI = asinf(tpos.z/RHO) + asinf(L2 * sin(GAMMA) / RHO), // Method 1
|
||||
PHI = ATAN2(tpos.z, RXY) + ATAN2(K2, K1), // Method 2
|
||||
|
||||
// Elbow motor angle measured from horizontal, same reference frame as shoulder angle (r+)
|
||||
PSI = PHI + GAMMA;
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ opt_enable VIKI2 BOOT_MARLIN_LOGO_ANIMATED SDSUPPORT AUTO_REPORT_SD_STATUS \
|
|||
AUTO_BED_LEVELING_3POINT DEBUG_LEVELING_FEATURE PROBE_PT_1 PROBE_PT_2 PROBE_PT_3 PROBE_WAKEUP_TIME_MS \
|
||||
EEPROM_SETTINGS EEPROM_CHITCHAT M114_DETAIL AUTO_REPORT_POSITION \
|
||||
NO_VOLUMETRICS EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES AUTOTEMP G38_PROBE_TARGET JOYSTICK \
|
||||
DIRECT_STEPPING DETECT_BROKEN_ENDSTOP \
|
||||
DIRECT_STEPPING DETECT_BROKEN_ENDSTOP SCALE_WORKSPACE ROTATE_WORKSPACE \
|
||||
FILAMENT_RUNOUT_SENSOR NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE Z_SAFE_HOMING FIL_RUNOUT3_PULLUP
|
||||
exec_test $1 $2 "Azteeg X3 Pro | EXTRUDERS 4 | VIKI2 | Servo Probe | Multiple runout sensors (x4)" "$3"
|
||||
|
||||
|
|
|
|||
|
|
@ -328,6 +328,8 @@ FILAMENT_LOAD_UNLOAD_GCODES = build_src_filter=+<src/gcode/feature/pa
|
|||
HAS_STEALTHCHOP = build_src_filter=+<src/gcode/feature/trinamic/M569.cpp>
|
||||
CNC_WORKSPACE_PLANES = build_src_filter=+<src/gcode/geometry/G17-G19.cpp>
|
||||
CNC_COORDINATE_SYSTEMS = build_src_filter=+<src/gcode/geometry/G53-G59.cpp>
|
||||
SCALE_WORKSPACE = build_src_filter=+<src/gcode/geometry/G50_G51.cpp>
|
||||
ROTATE_WORKSPACE = build_src_filter=+<src/gcode/geometry/G68_G69.cpp>
|
||||
HAS_HOME_OFFSET = build_src_filter=+<src/gcode/geometry/M206_M428.cpp>
|
||||
EXPECTED_PRINTER_CHECK = build_src_filter=+<src/gcode/host/M16.cpp>
|
||||
HOST_KEEPALIVE_FEATURE = build_src_filter=+<src/gcode/host/M113.cpp>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue