Commit e7efd3aa authored by MagoKimbra's avatar MagoKimbra

Fix

parent caf65063
......@@ -29,6 +29,9 @@
//Uncomment to enable autocalibration debug messages
#define DEBUG_MESSAGES
//Amount to lift head after probing a point
#define AUTOCAL_PROBELIFT 3 // mm
// Precision for G30 delta autocalibration function
#define AUTOCALIBRATION_PRECISION 0.1 // mm
......@@ -80,9 +83,9 @@
// ENDSTOP SETTINGS:
// Sets direction of endstop when homing; 1=MAX, -1=MIN
#define X_HOME_DIR 1 //DELTA MUST HAVE MAX ENDSTOP
#define Y_HOME_DIR 1 //DELTA MUST HAVE MAX ENDSTOP
#define Z_HOME_DIR 1 //DELTA MUST HAVE MAX ENDSTOP
#define X_HOME_DIR 1 // DELTA MUST HAVE MAX ENDSTOP
#define Y_HOME_DIR 1 // DELTA MUST HAVE MAX ENDSTOP
#define Z_HOME_DIR 1 // DELTA MUST HAVE MAX ENDSTOP
#define min_software_endstops true // If true, axis won't move to coordinates less than HOME_POS.
#define max_software_endstops true // If true, axis won't move to coordinates greater than the defined lengths below.
......
......@@ -376,7 +376,7 @@ bool target_direction;
};
static float z_offset;
static float bed_level_x, bed_level_y, bed_level_z;
static float bed_level_c = 20; //used for inital bed probe safe distance (to avoid crashing into bed)
static float bed_level_c = 20; // used for inital bed probe safe distance (to avoid crashing into bed)
static float bed_level_ox, bed_level_oy, bed_level_oz;
static int loopcount;
static bool home_all_axis = true;
......@@ -1635,9 +1635,9 @@ static void setup_for_endstop_move() {
float z_probe() {
enable_endstops(true);
//feedrate = homing_feedrate[X_AXIS];
//prepare_move_raw();
//st_synchronize();
feedrate = homing_feedrate[X_AXIS];
prepare_move_raw();
st_synchronize();
float start_z = current_position[Z_AXIS];
long start_steps = st_get_position(Z_AXIS);
......@@ -1672,13 +1672,10 @@ static void setup_for_endstop_move() {
float probe_bed_z, probe_z, probe_h, probe_l;
int probe_count;
for (int y = 3; y >= -3; y--)
{
for (int y = 3; y >= -3; y--) {
int dir = y % 2 ? -1 : 1;
for (int x = -3*dir; x != 4*dir; x += dir)
{
if (x*x + y*y < 11)
{
for (int x = -3*dir; x != 4*dir; x += dir) {
if (x*x + y*y < 11) {
destination[X_AXIS] = AUTOLEVEL_GRID * x - z_probe_offset[X_AXIS];
if (destination[X_AXIS]<X_MIN_POS) destination[X_AXIS]=X_MIN_POS;
if (destination[X_AXIS]>X_MAX_POS) destination[X_AXIS]=X_MAX_POS;
......@@ -1689,8 +1686,7 @@ static void setup_for_endstop_move() {
probe_z = -100;
probe_h = -100;
probe_l = 100;
do
{
do {
probe_bed_z = probe_z;
probe_z = z_probe() + z_offset;
if (probe_z > probe_h) probe_h = probe_z;
......@@ -1700,26 +1696,22 @@ static void setup_for_endstop_move() {
bed_level[x+3][3-y] = probe_bed_z;
}
else
{
else {
bed_level[x+3][3-y] = 0.0;
}
}
// For unprobed positions just copy nearest neighbor.
if (abs(y) >= 3)
{
if (abs(y) >= 3) {
bed_level[1][3-y] = bed_level[2][3-y];
bed_level[5][3-y] = bed_level[4][3-y];
}
if (abs(y) >=2)
{
if (abs(y) >=2) {
bed_level[0][3-y] = bed_level[1][3-y];
bed_level[6][3-y] = bed_level[5][3-y];
}
// Print calibration results for manual frame adjustment.
ECHO_S(DB);
for (int x = -3; x <= 3; x++)
{
for (int x = -3; x <= 3; x++) {
ECHO_VM(bed_level[x+3][3-y], " ", 3);
}
ECHO_E;
......@@ -1737,7 +1729,7 @@ static void setup_for_endstop_move() {
destination[Y_AXIS] = y - z_probe_offset[Y_AXIS];
if (destination[Y_AXIS] < Y_MIN_POS) destination[Y_AXIS] = Y_MIN_POS;
if (destination[Y_AXIS] > Y_MAX_POS) destination[Y_AXIS] = Y_MAX_POS;
destination[Z_AXIS] = bed_level_c - z_probe_offset[Z_AXIS] + 3;
destination[Z_AXIS] = bed_level_c - z_probe_offset[Z_AXIS] + AUTOCAL_PROBELIFT;
prepare_move();
st_synchronize();
......@@ -1763,15 +1755,13 @@ static void setup_for_endstop_move() {
float probe_l[7];
float range_h = 0, range_l = 0;
for(int x = 0; x < 7; x++)
{
for(int x = 0; x < 7; x++) {
probe_h[x] = -100;
probe_l[x] = 100;
}
// probe test loop
for(int x = 0; x < 3; x++)
{
for(int x = 0; x < 3; x++) {
bed_probe_all();
if (bed_level_c > probe_h[0]) probe_h[0] = bed_level_c;
......@@ -1789,8 +1779,7 @@ static void setup_for_endstop_move() {
if (bed_level_ox > probe_h[6]) probe_h[6] = bed_level_ox;
if (bed_level_ox < probe_l[6]) probe_l[6] = bed_level_ox;
}
for(int x = 0; x < 7; x++)
{
for(int x = 0; x < 7; x++) {
if (probe_h[x] - probe_l[x] > range_h) range_h = probe_h[x] - probe_l[x];
if (probe_h[x] - probe_l[x] < range_l) range_l = probe_h[x] - probe_l[x];
}
......@@ -1801,7 +1790,6 @@ static void setup_for_endstop_move() {
//Probe all bed positions & store carriage positions
bed_level_c = probe_bed(0.0, 0.0);
save_carriage_positions(0);
//Probe all bed positions & store carriage positions
bed_level_z = probe_bed(0.0, bed_radius);
save_carriage_positions(1);
bed_level_oy = probe_bed(-SIN_60 * bed_radius, COS_60 * bed_radius);
......@@ -1876,7 +1864,7 @@ static void setup_for_endstop_move() {
sync_plan_position();
// Move all carriages up together until the first endstop is hit.
for (int i = X_AXIS; i <= Z_AXIS; i++) destination[i] = 3 * max_length[Z_AXIS];
for (int i = X_AXIS; i <= Z_AXIS; i++) destination[i] = 3 * Z_MAX_LENGTH;
feedrate = 1.732 * homing_feedrate[X_AXIS];
line_to_destination();
st_synchronize();
......
/*
motion_control.c - high level interface for issuing motion commands
Part of Grbl
Copyright (c) 2009-2011 Simen Svale Skogsrud
Copyright (c) 2011 Sungeun K. Jeon
Grbl 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.
Grbl 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 Grbl. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Marlin.h"
#include "stepper.h"
#include "planner.h"
// The arc is approximated by generating a huge number of tiny, linear segments. The length of each
// segment is configured in settings.mm_per_arc_segment.
void mc_arc(float *position, float *target, float *offset, uint8_t axis_0, uint8_t axis_1,
uint8_t axis_linear, float feed_rate, float radius, uint8_t isclockwise, uint8_t extruder, uint8_t driver)
{
// int acceleration_manager_was_enabled = plan_is_acceleration_manager_enabled();
// plan_set_acceleration_manager_enabled(false); // disable acceleration management for the duration of the arc
float center_axis0 = position[axis_0] + offset[axis_0];
float center_axis1 = position[axis_1] + offset[axis_1];
float linear_travel = target[axis_linear] - position[axis_linear];
float extruder_travel = target[E_AXIS] - position[E_AXIS];
float r_axis0 = -offset[axis_0]; // Radius vector from center to current location
float r_axis1 = -offset[axis_1];
float rt_axis0 = target[axis_0] - center_axis0;
float rt_axis1 = target[axis_1] - center_axis1;
// CCW angle between position and target from circle center. Only one atan2() trig computation required.
float angular_travel = atan2(r_axis0*rt_axis1-r_axis1*rt_axis0, r_axis0*rt_axis0+r_axis1*rt_axis1);
if (angular_travel < 0) { angular_travel += 2*M_PI; }
if (isclockwise) { angular_travel -= 2*M_PI; }
//20141002:full circle for G03 did not work, e.g. G03 X80 Y80 I20 J0 F2000 is giving an Angle of zero so head is not moving
//to compensate when start pos = target pos && angle is zero -> angle = 2Pi
if (position[axis_0] == target[axis_0] && position[axis_1] == target[axis_1] && angular_travel == 0)
{
angular_travel += 2*M_PI;
}
//end fix G03
float millimeters_of_travel = hypot(angular_travel*radius, fabs(linear_travel));
if (millimeters_of_travel < 0.001) { return; }
uint16_t segments = floor(millimeters_of_travel/MM_PER_ARC_SEGMENT);
if(segments == 0) segments = 1;
/*
// Multiply inverse feed_rate to compensate for the fact that this movement is approximated
// by a number of discrete segments. The inverse feed_rate should be correct for the sum of
// all segments.
if (invert_feed_rate) { feed_rate *= segments; }
*/
float theta_per_segment = angular_travel/segments;
float linear_per_segment = linear_travel/segments;
float extruder_per_segment = extruder_travel/segments;
/* Vector rotation by transformation matrix: r is the original vector, r_T is the rotated vector,
and phi is the angle of rotation. Based on the solution approach by Jens Geisler.
r_T = [cos(phi) -sin(phi);
sin(phi) cos(phi] * r ;
For arc generation, the center of the circle is the axis of rotation and the radius vector is
defined from the circle center to the initial position. Each line segment is formed by successive
vector rotations. This requires only two cos() and sin() computations to form the rotation
matrix for the duration of the entire arc. Error may accumulate from numerical round-off, since
all double numbers are single precision on the Arduino. (True double precision will not have
round off issues for CNC applications.) Single precision error can accumulate to be greater than
tool precision in some cases. Therefore, arc path correction is implemented.
Small angle approximation may be used to reduce computation overhead further. This approximation
holds for everything, but very small circles and large mm_per_arc_segment values. In other words,
theta_per_segment would need to be greater than 0.1 rad and N_ARC_CORRECTION would need to be large
to cause an appreciable drift error. N_ARC_CORRECTION~=25 is more than small enough to correct for
numerical drift error. N_ARC_CORRECTION may be on the order a hundred(s) before error becomes an
issue for CNC machines with the single precision Arduino calculations.
This approximation also allows mc_arc to immediately insert a line segment into the planner
without the initial overhead of computing cos() or sin(). By the time the arc needs to be applied
a correction, the planner should have caught up to the lag caused by the initial mc_arc overhead.
This is important when there are successive arc motions.
*/
// Vector rotation matrix values
float cos_T = 1-0.5*theta_per_segment*theta_per_segment; // Small angle approximation
float sin_T = theta_per_segment;
float arc_target[4];
float sin_Ti;
float cos_Ti;
float r_axisi;
uint16_t i;
int8_t count = 0;
// Initialize the linear axis
arc_target[axis_linear] = position[axis_linear];
// Initialize the extruder axis
arc_target[E_AXIS] = position[E_AXIS];
for (i = 1; i<segments; i++) { // Increment (segments-1)
if (count < N_ARC_CORRECTION) {
// Apply vector rotation matrix
r_axisi = r_axis0*sin_T + r_axis1*cos_T;
r_axis0 = r_axis0*cos_T - r_axis1*sin_T;
r_axis1 = r_axisi;
count++;
} else {
// Arc correction to radius vector. Computed only every N_ARC_CORRECTION increments.
// Compute exact location by applying transformation matrix from initial radius vector(=-offset).
cos_Ti = cos(i*theta_per_segment);
sin_Ti = sin(i*theta_per_segment);
r_axis0 = -offset[axis_0]*cos_Ti + offset[axis_1]*sin_Ti;
r_axis1 = -offset[axis_0]*sin_Ti - offset[axis_1]*cos_Ti;
count = 0;
}
// Update arc_target location
arc_target[axis_0] = center_axis0 + r_axis0;
arc_target[axis_1] = center_axis1 + r_axis1;
arc_target[axis_linear] += linear_per_segment;
arc_target[E_AXIS] += extruder_per_segment;
clamp_to_software_endstops(arc_target);
plan_buffer_line(arc_target[X_AXIS], arc_target[Y_AXIS], arc_target[Z_AXIS], arc_target[E_AXIS], feed_rate, extruder, driver);
}
// Ensure last segment arrives at target location.
plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], feed_rate, extruder, driver);
// plan_set_acceleration_manager_enabled(acceleration_manager_was_enabled);
}
/*
motion_control.h - high level interface for issuing motion commands
Part of Grbl
Copyright (c) 2009-2011 Simen Svale Skogsrud
Copyright (c) 2011 Sungeun K. Jeon
Grbl 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.
Grbl 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 Grbl. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef motion_control_h
#define motion_control_h
// Execute an arc in offset mode format. position == current xyz, target == target xyz,
// offset == offset from current xyz, axis_XXX defines circle plane in tool space, axis_linear is
// the direction of helical travel, radius == circle radius, isclockwise boolean. Used
// for vector transformation direction.
void mc_arc(float *position, float *target, float *offset, unsigned char axis_0, unsigned char axis_1,
unsigned char axis_linear, float feed_rate, float radius, unsigned char isclockwise, uint8_t extruder, uint8_t driver);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment