First arcs version. (Arcs not working ok)

This commit is contained in:
Erik van der Zalm 2011-11-06 12:39:00 +01:00
parent 2e8e8878e5
commit 0b82465168
4 changed files with 1784 additions and 1479 deletions

View file

@ -1,245 +1,248 @@
#ifndef CONFIGURATION_H #ifndef CONFIGURATION_H
#define CONFIGURATION_H #define CONFIGURATION_H
//#define DEBUG_STEPS //#define DEBUG_STEPS
// BASIC SETTINGS: select your board type, thermistor type, axis scaling, and endstop configuration #define MM_PER_ARC_SEGMENT 1
#define N_ARC_CORRECTION 25
//// The following define selects which electronics board you have. Please choose the one that matches your setup
// MEGA/RAMPS up to 1.2 = 3, // BASIC SETTINGS: select your board type, thermistor type, axis scaling, and endstop configuration
// RAMPS 1.3 = 33
// Gen6 = 5, //// The following define selects which electronics board you have. Please choose the one that matches your setup
// Sanguinololu 1.2 and above = 62 // MEGA/RAMPS up to 1.2 = 3,
// Ultimaker = 7, // RAMPS 1.3 = 33
#define MOTHERBOARD 7 // Gen6 = 5,
//#define MOTHERBOARD 5 // Sanguinololu 1.2 and above = 62
// Ultimaker = 7,
#define MOTHERBOARD 7
//// Thermistor settings: //#define MOTHERBOARD 5
// 1 is 100k thermistor
// 2 is 200k thermistor
// 3 is mendel-parts thermistor //// Thermistor settings:
// 4 is 10k thermistor // 1 is 100k thermistor
// 5 is ParCan supplied 104GT-2 100K // 2 is 200k thermistor
// 6 is EPCOS 100k // 3 is mendel-parts thermistor
// 7 is 100k Honeywell thermistor 135-104LAG-J01 // 4 is 10k thermistor
#define THERMISTORHEATER_1 3 // 5 is ParCan supplied 104GT-2 100K
#define THERMISTORHEATER_2 3 // 6 is EPCOS 100k
#define THERMISTORBED 3 // 7 is 100k Honeywell thermistor 135-104LAG-J01
#define THERMISTORHEATER_1 3
//#define HEATER_0_USES_THERMISTOR #define THERMISTORHEATER_2 3
//#define HEATER_1_USES_THERMISTOR #define THERMISTORBED 3
#define HEATER_0_USES_AD595
//#define HEATER_1_USES_AD595 //#define HEATER_0_USES_THERMISTOR
//#define HEATER_1_USES_THERMISTOR
// Select one of these only to define how the bed temp is read. #define HEATER_0_USES_AD595
//#define BED_USES_THERMISTOR //#define HEATER_1_USES_AD595
//#define BED_USES_AD595
// Select one of these only to define how the bed temp is read.
#define HEATER_CHECK_INTERVAL 50 //#define BED_USES_THERMISTOR
#define BED_CHECK_INTERVAL 5000 //#define BED_USES_AD595
#define HEATER_CHECK_INTERVAL 50
//// Endstop Settings #define BED_CHECK_INTERVAL 5000
#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors
// The pullups are needed if you directly connect a mechanical endswitch between the signal and ground pins.
const bool ENDSTOPS_INVERTING = true; // set to true to invert the logic of the endstops. //// Endstop Settings
// For optos H21LOB set to true, for Mendel-Parts newer optos TCST2103 set to false #define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors
// The pullups are needed if you directly connect a mechanical endswitch between the signal and ground pins.
// This determines the communication speed of the printer const bool ENDSTOPS_INVERTING = true; // set to true to invert the logic of the endstops.
#define BAUDRATE 250000 // For optos H21LOB set to true, for Mendel-Parts newer optos TCST2103 set to false
//#define BAUDRATE 115200
//#define BAUDRATE 230400 // This determines the communication speed of the printer
#define BAUDRATE 250000
// Comment out (using // at the start of the line) to disable SD support: //#define BAUDRATE 115200
//#define BAUDRATE 230400
// #define ULTRA_LCD //any lcd
// Comment out (using // at the start of the line) to disable SD support:
#define ULTIPANEL
#define ULTIPANEL // #define ULTRA_LCD //any lcd
#ifdef ULTIPANEL
//#define NEWPANEL //enable this if you have a click-encoder panel #define ULTIPANEL
#define SDSUPPORT #define ULTIPANEL
#define ULTRA_LCD #ifdef ULTIPANEL
#define LCD_WIDTH 20 //#define NEWPANEL //enable this if you have a click-encoder panel
#define LCD_HEIGHT 4 #define SDSUPPORT
#else //no panel but just lcd #define ULTRA_LCD
#ifdef ULTRA_LCD #define LCD_WIDTH 20
#define LCD_WIDTH 16 #define LCD_HEIGHT 4
#define LCD_HEIGHT 2 #else //no panel but just lcd
#endif #ifdef ULTRA_LCD
#endif #define LCD_WIDTH 16
#define LCD_HEIGHT 2
#endif
//#define SDSUPPORT // Enable SD Card Support in Hardware Console #endif
//#define SDSUPPORT // Enable SD Card Support in Hardware Console
const int dropsegments=5; //everything with this number of steps will be ignored as move
//// ADVANCED SETTINGS - to tweak parameters
const int dropsegments=5; //everything with this number of steps will be ignored as move
#include "thermistortables.h"
//// ADVANCED SETTINGS - to tweak parameters
// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1
#define X_ENABLE_ON 0 #include "thermistortables.h"
#define Y_ENABLE_ON 0
#define Z_ENABLE_ON 0 // For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1
#define E_ENABLE_ON 0 #define X_ENABLE_ON 0
#define Y_ENABLE_ON 0
// Disables axis when it's not being used. #define Z_ENABLE_ON 0
#define DISABLE_X false #define E_ENABLE_ON 0
#define DISABLE_Y false
#define DISABLE_Z false // Disables axis when it's not being used.
#define DISABLE_E false #define DISABLE_X false
#define DISABLE_Y false
// Inverting axis direction #define DISABLE_Z false
#define INVERT_X_DIR true // for Mendel set to false, for Orca set to true #define DISABLE_E false
#define INVERT_Y_DIR false // for Mendel set to true, for Orca set to false
#define INVERT_Z_DIR true // for Mendel set to false, for Orca set to true // Inverting axis direction
#define INVERT_E_DIR false // for direct drive extruder v9 set to true, for geared extruder set to false #define INVERT_X_DIR true // for Mendel set to false, for Orca set to true
#define INVERT_Y_DIR false // for Mendel set to true, for Orca set to false
//// ENDSTOP SETTINGS: #define INVERT_Z_DIR true // for Mendel set to false, for Orca set to true
// Sets direction of endstops when homing; 1=MAX, -1=MIN #define INVERT_E_DIR false // for direct drive extruder v9 set to true, for geared extruder set to false
#define X_HOME_DIR -1
#define Y_HOME_DIR -1 //// ENDSTOP SETTINGS:
#define Z_HOME_DIR -1 // Sets direction of endstops when homing; 1=MAX, -1=MIN
#define X_HOME_DIR -1
#define min_software_endstops false //If true, axis won't move to coordinates less than zero. #define Y_HOME_DIR -1
#define max_software_endstops false //If true, axis won't move to coordinates greater than the defined lengths below. #define Z_HOME_DIR -1
#define X_MAX_LENGTH 210
#define Y_MAX_LENGTH 210 #define min_software_endstops false //If true, axis won't move to coordinates less than zero.
#define Z_MAX_LENGTH 210 #define max_software_endstops false //If true, axis won't move to coordinates greater than the defined lengths below.
#define X_MAX_LENGTH 210
//// MOVEMENT SETTINGS #define Y_MAX_LENGTH 210
#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E #define Z_MAX_LENGTH 210
//note: on bernhards ultimaker 200 200 12 are working well.
#define HOMING_FEEDRATE {50*60, 50*60, 12*60, 0} // set the homing speeds //// MOVEMENT SETTINGS
//the followint checks if an extrusion is existent in the move. if _not_, the speed of the move is set to the maximum speed. #define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
//!!!!!!Use only if you know that your printer works at the maximum declared speeds. //note: on bernhards ultimaker 200 200 12 are working well.
// works around the skeinforge cool-bug. There all moves are slowed to have a minimum layer time. However slow travel moves= ooze #define HOMING_FEEDRATE {50*60, 50*60, 12*60, 0} // set the homing speeds
#define TRAVELING_AT_MAXSPEED //the followint checks if an extrusion is existent in the move. if _not_, the speed of the move is set to the maximum speed.
#define AXIS_RELATIVE_MODES {false, false, false, false} //!!!!!!Use only if you know that your printer works at the maximum declared speeds.
// works around the skeinforge cool-bug. There all moves are slowed to have a minimum layer time. However slow travel moves= ooze
#define MAX_STEP_FREQUENCY 40000 // Max step frequency for Ultimaker (5000 pps / half step) #define TRAVELING_AT_MAXSPEED
#define AXIS_RELATIVE_MODES {false, false, false, false}
// default settings
#define MAX_STEP_FREQUENCY 40000 // Max step frequency for Ultimaker (5000 pps / half step)
#define DEFAULT_AXIS_STEPS_PER_UNIT {79.87220447,79.87220447,200*8/3,14} // default steps per unit for ultimaker
#define DEFAULT_MAX_FEEDRATE {160*60, 160*60, 10*60, 500000} // default settings
#define DEFAULT_MAX_ACCELERATION {9000,9000,150,10000} // X, Y, Z, E maximum start speed for accelerated moves. E default values are good for skeinforge 40+, for older versions raise them a lot.
#define DEFAULT_AXIS_STEPS_PER_UNIT {79.87220447,79.87220447,200*8/3,14} // default steps per unit for ultimaker
#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E max acceleration in mm/s^2 for printing moves #define DEFAULT_MAX_FEEDRATE {160*60, 160*60, 10*60, 500000}
#define DEFAULT_RETRACT_ACCELERATION 7000 // X, Y, Z and E max acceleration in mm/s^2 for r retracts #define DEFAULT_MAX_ACCELERATION {9000,9000,150,10000} // X, Y, Z, E maximum start speed for accelerated moves. E default values are good for skeinforge 40+, for older versions raise them a lot.
#define DEFAULT_MINIMUMFEEDRATE 10 // minimum feedrate #define DEFAULT_ACCELERATION 3000 // X, Y, Z and E max acceleration in mm/s^2 for printing moves
#define DEFAULT_MINTRAVELFEEDRATE 10 #define DEFAULT_RETRACT_ACCELERATION 7000 // X, Y, Z and E max acceleration in mm/s^2 for r retracts
// minimum time in microseconds that a movement needs to take if the buffer is emptied. Increase this number if you see blobs while printing high speed & high detail. It will slowdown on the detailed stuff. #define DEFAULT_MINIMUMFEEDRATE 10 // minimum feedrate
#define DEFAULT_MINSEGMENTTIME 20000 #define DEFAULT_MINTRAVELFEEDRATE 10
#define DEFAULT_XYJERK 30.0*60
#define DEFAULT_ZJERK 10.0*60 // minimum time in microseconds that a movement needs to take if the buffer is emptied. Increase this number if you see blobs while printing high speed & high detail. It will slowdown on the detailed stuff.
#define DEFAULT_MINSEGMENTTIME 20000
#define DEFAULT_XYJERK 30.0*60
// The watchdog waits for the watchperiod in milliseconds whenever an M104 or M109 increases the target temperature #define DEFAULT_ZJERK 10.0*60
//this enables the watchdog interrupt.
#define USE_WATCHDOG
//you cannot reboot on a mega2560 due to a bug in he bootloader. Hence, you have to reset manually, and this is done hereby: // The watchdog waits for the watchperiod in milliseconds whenever an M104 or M109 increases the target temperature
#define RESET_MANUAL //this enables the watchdog interrupt.
#define USE_WATCHDOG
#define WATCHDOG_TIMEOUT 4 //you cannot reboot on a mega2560 due to a bug in he bootloader. Hence, you have to reset manually, and this is done hereby:
#define RESET_MANUAL
#define WATCHDOG_TIMEOUT 4
//// Experimental watchdog and minimal temp
// The watchdog waits for the watchperiod in milliseconds whenever an M104 or M109 increases the target temperature
// If the temperature has not increased at the end of that period, the target temperature is set to zero. It can be reset with another M104/M109
//#define WATCHPERIOD 5000 //5 seconds //// Experimental watchdog and minimal temp
// The watchdog waits for the watchperiod in milliseconds whenever an M104 or M109 increases the target temperature
// Actual temperature must be close to target for this long before M109 returns success // If the temperature has not increased at the end of that period, the target temperature is set to zero. It can be reset with another M104/M109
//#define TEMP_RESIDENCY_TIME 20 // (seconds) //#define WATCHPERIOD 5000 //5 seconds
//#define TEMP_HYSTERESIS 5 // (C°) range of +/- temperatures considered "close" to the target one
// Actual temperature must be close to target for this long before M109 returns success
//// The minimal temperature defines the temperature below which the heater will not be enabled //#define TEMP_RESIDENCY_TIME 20 // (seconds)
#define HEATER_0_MINTEMP 5 //#define TEMP_HYSTERESIS 5 // (C°) range of +/- temperatures considered "close" to the target one
//#define HEATER_1_MINTEMP 5
//#define BED_MINTEMP 5 //// The minimal temperature defines the temperature below which the heater will not be enabled
#define HEATER_0_MINTEMP 5
//#define HEATER_1_MINTEMP 5
// When temperature exceeds max temp, your heater will be switched off. //#define BED_MINTEMP 5
// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure!
// You should use MINTEMP for thermistor short/failure protection.
#define HEATER_0_MAXTEMP 275 // When temperature exceeds max temp, your heater will be switched off.
//#define_HEATER_1_MAXTEMP 275 // This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure!
//#define BED_MAXTEMP 150 // You should use MINTEMP for thermistor short/failure protection.
#define HEATER_0_MAXTEMP 275
//#define_HEATER_1_MAXTEMP 275
//#define BED_MAXTEMP 150
#define PIDTEMP
#ifdef PIDTEMP
/// PID settings:
// Uncomment the following line to enable PID support. #define PIDTEMP
//#define SMOOTHING #ifdef PIDTEMP
//#define SMOOTHFACTOR 5.0 /// PID settings:
//float current_raw_average=0; // Uncomment the following line to enable PID support.
#define K1 0.95 //smoothing of the PID //#define SMOOTHING
//#define PID_DEBUG // Sends debug data to the serial port. //#define SMOOTHFACTOR 5.0
//#define PID_OPENLOOP 1 // Puts PID in open loop. M104 sets the output power in % //float current_raw_average=0;
#define PID_MAX 255 // limits current to nozzle #define K1 0.95 //smoothing of the PID
#define PID_INTEGRAL_DRIVE_MAX 255 //#define PID_DEBUG // Sends debug data to the serial port.
#define PID_dT 0.1 //#define PID_OPENLOOP 1 // Puts PID in open loop. M104 sets the output power in %
//machine with red silicon: 1950:45 second ; with fan fully blowin 3000:47 #define PID_MAX 255 // limits current to nozzle
#define PID_INTEGRAL_DRIVE_MAX 255
#define PID_CRITIAL_GAIN 3000 #define PID_dT 0.1
#define PID_SWING_AT_CRITIAL 45 //seconds //machine with red silicon: 1950:45 second ; with fan fully blowin 3000:47
#define PIDIADD 5
/* #define PID_CRITIAL_GAIN 3000
//PID according to Ziegler-Nichols method #define PID_SWING_AT_CRITIAL 45 //seconds
float Kp = 0.6*PID_CRITIAL_GAIN; #define PIDIADD 5
float Ki =PIDIADD+2*Kp/PID_SWING_AT_CRITIAL*PID_dT; /*
float Kd = Kp*PID_SWING_AT_CRITIAL/8./PID_dT; //PID according to Ziegler-Nichols method
*/ float Kp = 0.6*PID_CRITIAL_GAIN;
//PI according to Ziegler-Nichols method float Ki =PIDIADD+2*Kp/PID_SWING_AT_CRITIAL*PID_dT;
#define DEFAULT_Kp (PID_CRITIAL_GAIN/2.2) float Kd = Kp*PID_SWING_AT_CRITIAL/8./PID_dT;
#define DEFAULT_Ki (1.2*Kp/PID_SWING_AT_CRITIAL*PID_dT) */
#define DEFAULT_Kd (0) //PI according to Ziegler-Nichols method
#define DEFAULT_Kp (PID_CRITIAL_GAIN/2.2)
#define PID_ADD_EXTRUSION_RATE #define DEFAULT_Ki (1.2*Kp/PID_SWING_AT_CRITIAL*PID_dT)
#ifdef PID_ADD_EXTRUSION_RATE #define DEFAULT_Kd (0)
#define DEFAULT_Kc (5) //heatingpower=Kc*(e_speed)
#endif #define PID_ADD_EXTRUSION_RATE
#endif // PIDTEMP #ifdef PID_ADD_EXTRUSION_RATE
#define DEFAULT_Kc (5) //heatingpower=Kc*(e_speed)
// extruder advance constant (s2/mm3) #endif
// #endif // PIDTEMP
// advance (steps) = STEPS_PER_CUBIC_MM_E * EXTUDER_ADVANCE_K * cubic mm per second ^ 2
// // extruder advance constant (s2/mm3)
// hooke's law says: force = k * distance //
// bernoulli's priniciple says: v ^ 2 / 2 + g . h + pressure / density = constant // advance (steps) = STEPS_PER_CUBIC_MM_E * EXTUDER_ADVANCE_K * cubic mm per second ^ 2
// so: v ^ 2 is proportional to number of steps we advance the extruder //
//#define ADVANCE // hooke's law says: force = k * distance
// bernoulli's priniciple says: v ^ 2 / 2 + g . h + pressure / density = constant
#ifdef ADVANCE // so: v ^ 2 is proportional to number of steps we advance the extruder
#define EXTRUDER_ADVANCE_K .3 //#define ADVANCE
#define D_FILAMENT 1.7 #ifdef ADVANCE
#define STEPS_MM_E 65 #define EXTRUDER_ADVANCE_K .3
#define EXTRUTION_AREA (0.25 * D_FILAMENT * D_FILAMENT * 3.14159)
#define STEPS_PER_CUBIC_MM_E (axis_steps_per_unit[E_AXIS]/ EXTRUTION_AREA) #define D_FILAMENT 1.7
#define STEPS_MM_E 65
#endif // ADVANCE #define EXTRUTION_AREA (0.25 * D_FILAMENT * D_FILAMENT * 3.14159)
#define STEPS_PER_CUBIC_MM_E (axis_steps_per_unit[E_AXIS]/ EXTRUTION_AREA)
// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, e.g. 8,16,32
#if defined SDSUPPORT #endif // ADVANCE
// The number of linear motions that can be in the plan at any give time.
#define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller // THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, e.g. 8,16,32
#else #if defined SDSUPPORT
#define BLOCK_BUFFER_SIZE 16 // maximize block buffer // The number of linear motions that can be in the plan at any give time.
#endif #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller
#else
#define BLOCK_BUFFER_SIZE 16 // maximize block buffer
#endif #endif
#endif

File diff suppressed because it is too large Load diff

133
Marlin/motion_control.cpp Normal file
View file

@ -0,0 +1,133 @@
/*
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 "motion_control.h"
#include "Configuration.h"
#include "Marlin.h"
//#include <util/delay.h>
//#include <math.h>
//#include <stdlib.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)
{
// 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
Serial.println("mc_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 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; }
float millimeters_of_travel = hypot(angular_travel*radius, fabs(linear_travel));
if (millimeters_of_travel == 0.0) { return; }
uint16_t segments = floor(millimeters_of_travel/MM_PER_ARC_SEGMENT);
/*
// 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;
/* 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[3];
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];
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;
plan_buffer_line(arc_target[X_AXIS], arc_target[Y_AXIS], arc_target[Z_AXIS], target[E_AXIS], feed_rate);
}
// Ensure last segment arrives at target location.
plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], feed_rate);
// plan_set_acceleration_manager_enabled(acceleration_manager_was_enabled);
}

32
Marlin/motion_control.h Normal file
View file

@ -0,0 +1,32 @@
/*
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);
#endif