From 4f68edbba2312c9a4b8f9fe28ef508dd50f3f35b Mon Sep 17 00:00:00 2001 From: ashelly Date: Mon, 8 Sep 2014 22:10:59 -0400 Subject: [PATCH 01/40] Alarm if limits engaged on homing --- motion_control.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/motion_control.c b/motion_control.c index 66633d1..3b0b171 100644 --- a/motion_control.c +++ b/motion_control.c @@ -240,6 +240,18 @@ void mc_dwell(float seconds) // executing the homing cycle. This prevents incorrect buffered plans after homing. void mc_homing_cycle() { + uint8_t limits_on; + if (bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { + limits_on = (LIMIT_PIN ^ LIMIT_MASK); + } else { + limits_on = (LIMIT_PIN & LIMIT_MASK); + } + if (limits_on) { + mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown. + bit_true_atomic(sys.execute, (EXEC_ALARM | EXEC_CRIT_EVENT)); // Indicate homing limit critical event + return; + } + sys.state = STATE_HOMING; // Set system state variable limits_disable(); // Disable hard limits pin change register for cycle duration From f78eebcebf00319ac2901a6b54430e78d800e837 Mon Sep 17 00:00:00 2001 From: Elijah Insua Date: Sun, 14 Sep 2014 14:43:10 -0700 Subject: [PATCH 02/40] add MOTION_MODE_PROBE_NO_ERROR --- gcode.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gcode.h b/gcode.h index 8a29aab..fc28d32 100644 --- a/gcode.h +++ b/gcode.h @@ -71,8 +71,9 @@ #define MOTION_MODE_LINEAR 1 // G1 #define MOTION_MODE_CW_ARC 2 // G2 #define MOTION_MODE_CCW_ARC 3 // G3 -#define MOTION_MODE_PROBE 4 // G38.2 -#define MOTION_MODE_NONE 5 // G80 +#define MOTION_MODE_PROBE 4 // G38.2, G38.4 +#define MOTION_MODE_PROBE_NO_ERROR 5 // G38.3, G38.5 +#define MOTION_MODE_NONE 6 // G80 // Modal Group G2: Plane select #define PLANE_SELECT_XY 0 // G17 (Default: Must be zero) From 0f7806938d0325da15faffc7c23fe1e5ed8d0319 Mon Sep 17 00:00:00 2001 From: Elijah Insua Date: Sun, 14 Sep 2014 15:36:25 -0700 Subject: [PATCH 03/40] install G38.{3,4,5} --- gcode.c | 22 +++++++++++++++++----- motion_control.c | 2 +- probe.c | 6 ++++-- system.h | 1 + 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/gcode.c b/gcode.c index 1977d83..f1f4e97 100644 --- a/gcode.c +++ b/gcode.c @@ -210,11 +210,23 @@ uint8_t gc_execute_line(char *line) case 3: gc_block.modal.motion = MOTION_MODE_CCW_ARC; break; // G3 case 38: switch(mantissa) { - case 20: gc_block.modal.motion = MOTION_MODE_PROBE; break; // G38.2 - // NOTE: If G38.3+ are enabled, change mantissa variable type to uint16_t. - // case 30: gc_block.modal.motion = MOTION_MODE_PROBE_NO_ERROR; break; // G38.3 Not supported. - // case 40: // Not supported. - // case 50: // Not supported. + case 20: + sys.probe_away = false; + gc_block.modal.motion = MOTION_MODE_PROBE; + break; // G38.2 + case 30: + sys.probe_away = false; + gc_block.modal.motion = MOTION_MODE_PROBE_NO_ERROR; + break; // G38.3 + case 40: + sys.probe_away = true; + gc_block.modal.motion = MOTION_MODE_PROBE; + break; // G38.4 + case 50: + sys.probe_away = true; + gc_block.modal.motion = MOTION_MODE_PROBE_NO_ERROR; + break; // G38.5 + default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported G38.x command] } mantissa = 0; // Set to zero to indicate valid non-integer G command. diff --git a/motion_control.c b/motion_control.c index 66633d1..01fa0f2 100644 --- a/motion_control.c +++ b/motion_control.c @@ -289,7 +289,7 @@ void mc_homing_cycle() uint8_t auto_start_state = sys.auto_start; // Store run state // After syncing, check if probe is already triggered. If so, halt and issue alarm. - if (probe_get_state()) { + if ((sys.probe_away << PROBE_BIT) ^ probe_get_state()) { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); protocol_execute_runtime(); } diff --git a/probe.c b/probe.c index 00dde47..581f9f1 100644 --- a/probe.c +++ b/probe.c @@ -37,6 +37,8 @@ void probe_init() PROBE_PORT |= PROBE_MASK; // Enable internal pull-up resistors. Normal high operation. probe_invert_mask = PROBE_MASK; } + + sys.probe_away = false; } @@ -49,8 +51,8 @@ uint8_t probe_get_state() { return((PROBE_PIN & PROBE_MASK) ^ probe_invert_mask) // NOTE: This function must be extremely efficient as to not bog down the stepper ISR. void probe_state_monitor() { - if (sys.probe_state == PROBE_ACTIVE) { - if (probe_get_state()) { + if (sys.probe_state == PROBE_ACTIVE) { + if ((sys.probe_away << PROBE_BIT) ^ probe_get_state()) { sys.probe_state = PROBE_OFF; memcpy(sys.probe_position, sys.position, sizeof(float)*N_AXIS); bit_true(sys.execute, EXEC_FEED_HOLD); diff --git a/system.h b/system.h index 93ab2b9..ddd7625 100644 --- a/system.h +++ b/system.h @@ -79,6 +79,7 @@ typedef struct { uint8_t auto_start; // Planner auto-start flag. Toggled off during feed hold. Defaulted by settings. volatile uint8_t probe_state; // Probing state value. Used to coordinate the probing cycle with stepper ISR. int32_t probe_position[N_AXIS]; // Last probe position in machine coordinates and steps. + uint8_t probe_away; // probe away from work by reversing the switch direction (G38.4, G38.5) } system_t; extern system_t sys; From b89d194466e7f69d7d184a5f8c0df794b8b41682 Mon Sep 17 00:00:00 2001 From: Elijah Insua Date: Sun, 14 Sep 2014 15:42:31 -0700 Subject: [PATCH 04/40] utilize MOTION_MODE_PROBE_NO_ERROR --- gcode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gcode.c b/gcode.c index f1f4e97..27ed4e4 100644 --- a/gcode.c +++ b/gcode.c @@ -982,6 +982,7 @@ uint8_t gc_execute_line(char *line) #endif break; case MOTION_MODE_PROBE: + case MOTION_MODE_PROBE_NO_ERROR: // NOTE: gc_block.values.xyz is returned from mc_probe_cycle with the updated position value. So // upon a successful probing cycle, the machine position and the returned value should be the same. #ifdef USE_LINE_NUMBERS From fd0db24199738a0a0dfac9ddf03acee521f18896 Mon Sep 17 00:00:00 2001 From: Markus Schulz Date: Wed, 17 Sep 2014 18:56:25 -0400 Subject: [PATCH 05/40] If variable spindle is defined print S value via $G command. --- report.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/report.c b/report.c index 32720eb..92033b3 100644 --- a/report.c +++ b/report.c @@ -330,6 +330,11 @@ void report_gcode_modes() printPgmString(PSTR(" F")); printFloat_RateValue(gc_state.feed_rate); + + #ifdef VARIABLE_SPINDLE + printPgmString(PSTR(" S")); + printFloat_RateValue(gc_state.spindle_speed); + #endif printPgmString(PSTR("]\r\n")); } From 5b97a79b6d74fa99fe32246f20ce5f275e1279c4 Mon Sep 17 00:00:00 2001 From: ashelly Date: Wed, 17 Sep 2014 23:41:52 -0400 Subject: [PATCH 06/40] No false alarm if other bits in port are set. --- motion_control.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/motion_control.c b/motion_control.c index 3b0b171..2208a93 100644 --- a/motion_control.c +++ b/motion_control.c @@ -242,7 +242,7 @@ void mc_homing_cycle() { uint8_t limits_on; if (bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { - limits_on = (LIMIT_PIN ^ LIMIT_MASK); + limits_on = ((~LIMIT_PIN) & LIMIT_MASK); } else { limits_on = (LIMIT_PIN & LIMIT_MASK); } From 322feba52feedd4600f4cde72ef10ea5aa235738 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Sat, 20 Sep 2014 08:50:27 -0600 Subject: [PATCH 07/40] Minor settings number overflow bug fix. - The `x` in `$x=val` would overflow when a value larger than 255 was entered and passed to Grbl. This resulted with unintended parameters being set by the overflow value. To fix, simply check for values larger than 255 and error out. --- system.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system.c b/system.c index 9079820..b8e2f6b 100644 --- a/system.c +++ b/system.c @@ -190,7 +190,7 @@ uint8_t system_execute_line(char *line) } } else { // Store global setting. if(!read_float(line, &char_counter, &value)) { return(STATUS_BAD_NUMBER_FORMAT); } - if(line[char_counter] != 0) { return(STATUS_INVALID_STATEMENT); } + if((line[char_counter] != 0) || (parameter > 255)) { return(STATUS_INVALID_STATEMENT); } return(settings_store_global_setting((uint8_t)parameter, value)); } } From 39cf82294439c7e7b1599b9f919d27290ed7a5cc Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Sat, 20 Sep 2014 10:41:31 -0600 Subject: [PATCH 08/40] Edit hard limit check at start of homing cycle --- gcode.h | 1 + limits.c | 1 + motion_control.c | 13 ++++++------- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/gcode.h b/gcode.h index 8a29aab..81ae4d9 100644 --- a/gcode.h +++ b/gcode.h @@ -164,6 +164,7 @@ typedef struct { float spindle_speed; // RPM float feed_rate; // Millimeters/min uint8_t tool; // Tracks tool number. NOT USED. +// int32_t line_number; // Last line number sent float position[N_AXIS]; // Where the interpreter considers the tool to be at this point in the code diff --git a/limits.c b/limits.c index 12cc248..4538dcb 100644 --- a/limits.c +++ b/limits.c @@ -122,6 +122,7 @@ void limits_disable() // mask, which prevents the stepper algorithm from executing step pulses. Homing motions typically // circumvent the processes for executing motions in normal operation. // NOTE: Only the abort runtime command can interrupt this process. +// TODO: Move limit pin-specific calls to a general function for portability. void limits_go_home(uint8_t cycle_mask) { if (sys.abort) { return; } // Block if system reset has been issued. diff --git a/motion_control.c b/motion_control.c index 2208a93..66e9701 100644 --- a/motion_control.c +++ b/motion_control.c @@ -240,13 +240,12 @@ void mc_dwell(float seconds) // executing the homing cycle. This prevents incorrect buffered plans after homing. void mc_homing_cycle() { - uint8_t limits_on; - if (bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { - limits_on = ((~LIMIT_PIN) & LIMIT_MASK); - } else { - limits_on = (LIMIT_PIN & LIMIT_MASK); - } - if (limits_on) { + // Check and abort homing cycle, if hard limits are already enabled. Helps prevent problems + // with machines with limits wired on both ends of travel to one limit pin. + // TODO: Move the pin-specific LIMIT_PIN call to limits.c as a function. + uint8_t limit_state = (LIMIT_PIN & LIMIT_MASK); + if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { limit_state ^= LIMIT_MASK; } + if (limit_state) { mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown. bit_true_atomic(sys.execute, (EXEC_ALARM | EXEC_CRIT_EVENT)); // Indicate homing limit critical event return; From 5406fa939a1fd669fd58b5509e7a9a46ee975d47 Mon Sep 17 00:00:00 2001 From: Elijah Insua Date: Mon, 22 Sep 2014 13:29:02 -0700 Subject: [PATCH 09/40] cleanup global var and push probe mode into probe_get_state --- gcode.c | 34 ++++++++++++++++------------------ gcode.h | 5 ++--- motion_control.c | 9 +++++---- motion_control.h | 4 ++-- probe.c | 12 ++++++------ probe.h | 8 +++++++- system.h | 1 - 7 files changed, 38 insertions(+), 35 deletions(-) diff --git a/gcode.c b/gcode.c index 27ed4e4..9d0f81d 100644 --- a/gcode.c +++ b/gcode.c @@ -124,7 +124,7 @@ uint8_t gc_execute_line(char *line) float value; uint8_t int_value = 0; uint8_t mantissa = 0; // NOTE: For mantissa values > 255, variable type must be changed to uint16_t. - + uint8_t probe_mode = 0; while (line[char_counter] != 0) { // Loop until no more g-code words in line. @@ -210,22 +210,21 @@ uint8_t gc_execute_line(char *line) case 3: gc_block.modal.motion = MOTION_MODE_CCW_ARC; break; // G3 case 38: switch(mantissa) { - case 20: - sys.probe_away = false; + case 20: // G38.2 gc_block.modal.motion = MOTION_MODE_PROBE; - break; // G38.2 - case 30: - sys.probe_away = false; - gc_block.modal.motion = MOTION_MODE_PROBE_NO_ERROR; - break; // G38.3 - case 40: - sys.probe_away = true; + break; + case 30: // G38.3 gc_block.modal.motion = MOTION_MODE_PROBE; - break; // G38.4 - case 50: - sys.probe_away = true; - gc_block.modal.motion = MOTION_MODE_PROBE_NO_ERROR; - break; // G38.5 + probe_mode = PROBE_NO_ERROR; + break; + case 40: // G38.4 + gc_block.modal.motion = MOTION_MODE_PROBE; + probe_mode = PROBE_AWAY; + break; + case 50: // G38.5 + gc_block.modal.motion = MOTION_MODE_PROBE; + probe_mode = PROBE_AWAY | PROBE_NO_ERROR; + break; default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported G38.x command] } @@ -982,13 +981,12 @@ uint8_t gc_execute_line(char *line) #endif break; case MOTION_MODE_PROBE: - case MOTION_MODE_PROBE_NO_ERROR: // NOTE: gc_block.values.xyz is returned from mc_probe_cycle with the updated position value. So // upon a successful probing cycle, the machine position and the returned value should be the same. #ifdef USE_LINE_NUMBERS - mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, gc_block.values.n); + mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, probe_mode, gc_block.values.n); #else - mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate); + mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, probe_mode); #endif } diff --git a/gcode.h b/gcode.h index fc28d32..98efe23 100644 --- a/gcode.h +++ b/gcode.h @@ -71,9 +71,8 @@ #define MOTION_MODE_LINEAR 1 // G1 #define MOTION_MODE_CW_ARC 2 // G2 #define MOTION_MODE_CCW_ARC 3 // G3 -#define MOTION_MODE_PROBE 4 // G38.2, G38.4 -#define MOTION_MODE_PROBE_NO_ERROR 5 // G38.3, G38.5 -#define MOTION_MODE_NONE 6 // G80 +#define MOTION_MODE_PROBE 4 // G38.2, G38.3, G38.4, G38.5 +#define MOTION_MODE_NONE 5 // G80 // Modal Group G2: Plane select #define PLANE_SELECT_XY 0 // G17 (Default: Must be zero) diff --git a/motion_control.c b/motion_control.c index 01fa0f2..b069267 100644 --- a/motion_control.c +++ b/motion_control.c @@ -276,9 +276,9 @@ void mc_homing_cycle() // Perform tool length probe cycle. Requires probe switch. // NOTE: Upon probe failure, the program will be stopped and placed into ALARM state. #ifdef USE_LINE_NUMBERS - void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, int32_t line_number) + void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, uint8_t mode, int32_t line_number) #else - void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate) + void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, uint8_t mode) #endif { // TODO: Need to update this cycle so it obeys a non-auto cycle start. @@ -289,7 +289,7 @@ void mc_homing_cycle() uint8_t auto_start_state = sys.auto_start; // Store run state // After syncing, check if probe is already triggered. If so, halt and issue alarm. - if ((sys.probe_away << PROBE_BIT) ^ probe_get_state()) { + if (probe_get_state(mode)) { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); protocol_execute_runtime(); } @@ -303,7 +303,7 @@ void mc_homing_cycle() #endif // Activate the probing monitor in the stepper module. - sys.probe_state = PROBE_ACTIVE; + sys.probe_state = PROBE_ACTIVE | mode; // Perform probing cycle. Wait here until probe is triggered or motion completes. bit_true_atomic(sys.execute, EXEC_CYCLE_START); @@ -314,6 +314,7 @@ void mc_homing_cycle() // Probing motion complete. If the probe has not been triggered, error out. if (sys.probe_state == PROBE_ACTIVE) { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); } + if (sys.probe_state & PROBE_ACTIVE) { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); } protocol_execute_runtime(); // Check and execute run-time commands if (sys.abort) { return; } // Check for system abort diff --git a/motion_control.h b/motion_control.h index 5a1d8c9..54aa1e5 100644 --- a/motion_control.h +++ b/motion_control.h @@ -58,9 +58,9 @@ void mc_homing_cycle(); // Perform tool length probe cycle. Requires probe switch. #ifdef USE_LINE_NUMBERS -void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, int32_t line_number); +void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, uint8_t motion, int32_t line_number); #else -void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate); +void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, uint8_t motion); #endif // Performs system reset. If in motion state, kills all motion and sets system alarm. diff --git a/probe.c b/probe.c index 581f9f1..5a65939 100644 --- a/probe.c +++ b/probe.c @@ -37,22 +37,22 @@ void probe_init() PROBE_PORT |= PROBE_MASK; // Enable internal pull-up resistors. Normal high operation. probe_invert_mask = PROBE_MASK; } - - sys.probe_away = false; } // Returns the probe pin state. Triggered = true. Called by gcode parser and probe state monitor. -uint8_t probe_get_state() { return((PROBE_PIN & PROBE_MASK) ^ probe_invert_mask); } - +uint8_t probe_get_state(uint8_t mode) { + mode = ((mode >> PROBE_AWAY_BIT) & 1) << PROBE_BIT; + return mode ^ ((PROBE_PIN & PROBE_MASK) ^ probe_invert_mask); +} // Monitors probe pin state and records the system position when detected. Called by the // stepper ISR per ISR tick. // NOTE: This function must be extremely efficient as to not bog down the stepper ISR. void probe_state_monitor() { - if (sys.probe_state == PROBE_ACTIVE) { - if ((sys.probe_away << PROBE_BIT) ^ probe_get_state()) { + if (sys.probe_state != PROBE_OFF) { + if (probe_get_state(sys.probe_state)) { sys.probe_state = PROBE_OFF; memcpy(sys.probe_position, sys.position, sizeof(float)*N_AXIS); bit_true(sys.execute, EXEC_FEED_HOLD); diff --git a/probe.h b/probe.h index 81fb55b..5986d86 100644 --- a/probe.h +++ b/probe.h @@ -25,12 +25,18 @@ #define PROBE_OFF 0 // No probing. (Must be zero.) #define PROBE_ACTIVE 1 // Actively watching the input pin. +// Probe direction and error modes +#define PROBE_AWAY 2 // G38.4, G38.5 +#define PROBE_NO_ERROR 4 // G38.3, G38.5 + +#define PROBE_AWAY_BIT 1 +#define PROBE_NO_ERROR_BIT 2 // Probe pin initialization routine. void probe_init(); // Returns probe pin state. -uint8_t probe_get_state(); +uint8_t probe_get_state(uint8_t mode); // Monitors probe pin state and records the system position when detected. Called by the // stepper ISR per ISR tick. diff --git a/system.h b/system.h index ddd7625..93ab2b9 100644 --- a/system.h +++ b/system.h @@ -79,7 +79,6 @@ typedef struct { uint8_t auto_start; // Planner auto-start flag. Toggled off during feed hold. Defaulted by settings. volatile uint8_t probe_state; // Probing state value. Used to coordinate the probing cycle with stepper ISR. int32_t probe_position[N_AXIS]; // Last probe position in machine coordinates and steps. - uint8_t probe_away; // probe away from work by reversing the switch direction (G38.4, G38.5) } system_t; extern system_t sys; From 5c07acd9fae3f231f59a363cd721f3b41c6bc34e Mon Sep 17 00:00:00 2001 From: Elijah Insua Date: Mon, 22 Sep 2014 13:39:51 -0700 Subject: [PATCH 10/40] test only for & PROBE_ACTIVE --- motion_control.c | 1 - 1 file changed, 1 deletion(-) diff --git a/motion_control.c b/motion_control.c index b069267..b74bb7c 100644 --- a/motion_control.c +++ b/motion_control.c @@ -313,7 +313,6 @@ void mc_homing_cycle() } while ((sys.state != STATE_IDLE) && (sys.state != STATE_QUEUED)); // Probing motion complete. If the probe has not been triggered, error out. - if (sys.probe_state == PROBE_ACTIVE) { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); } if (sys.probe_state & PROBE_ACTIVE) { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); } protocol_execute_runtime(); // Check and execute run-time commands if (sys.abort) { return; } // Check for system abort From b920838109c89941776dd266d8a6e804a8634ea2 Mon Sep 17 00:00:00 2001 From: Elijah Insua Date: Mon, 22 Sep 2014 14:05:35 -0700 Subject: [PATCH 11/40] bump mantissa to uint16_t to enable G38.5 --- gcode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcode.c b/gcode.c index 9d0f81d..4afa027 100644 --- a/gcode.c +++ b/gcode.c @@ -123,7 +123,7 @@ uint8_t gc_execute_line(char *line) char letter; float value; uint8_t int_value = 0; - uint8_t mantissa = 0; // NOTE: For mantissa values > 255, variable type must be changed to uint16_t. + uint16_t mantissa = 0; // NOTE: For mantissa values > 255, variable type must be changed to uint16_t. uint8_t probe_mode = 0; while (line[char_counter] != 0) { // Loop until no more g-code words in line. From 3392a8b2c89ce28967af52ee365d38c97ef925c3 Mon Sep 17 00:00:00 2001 From: Elijah Insua Date: Mon, 22 Sep 2014 14:12:25 -0700 Subject: [PATCH 12/40] add/install probe_errors_enabled in mc_probe_cycle --- motion_control.c | 6 ++++-- probe.c | 4 ++++ probe.h | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/motion_control.c b/motion_control.c index b74bb7c..66cb9ac 100644 --- a/motion_control.c +++ b/motion_control.c @@ -289,7 +289,7 @@ void mc_homing_cycle() uint8_t auto_start_state = sys.auto_start; // Store run state // After syncing, check if probe is already triggered. If so, halt and issue alarm. - if (probe_get_state(mode)) { + if (probe_get_state(mode) && probe_errors_enabled(mode)) { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); protocol_execute_runtime(); } @@ -313,7 +313,9 @@ void mc_homing_cycle() } while ((sys.state != STATE_IDLE) && (sys.state != STATE_QUEUED)); // Probing motion complete. If the probe has not been triggered, error out. - if (sys.probe_state & PROBE_ACTIVE) { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); } + if (sys.probe_state & PROBE_ACTIVE && probe_errors_enabled(mode)) { + bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); + } protocol_execute_runtime(); // Check and execute run-time commands if (sys.abort) { return; } // Check for system abort diff --git a/probe.c b/probe.c index 5a65939..7d45fe6 100644 --- a/probe.c +++ b/probe.c @@ -46,6 +46,10 @@ uint8_t probe_get_state(uint8_t mode) { return mode ^ ((PROBE_PIN & PROBE_MASK) ^ probe_invert_mask); } +uint8_t probe_errors_enabled(uint8_t mode) { + return !(mode & PROBE_NO_ERROR); +} + // Monitors probe pin state and records the system position when detected. Called by the // stepper ISR per ISR tick. // NOTE: This function must be extremely efficient as to not bog down the stepper ISR. diff --git a/probe.h b/probe.h index 5986d86..5a2006d 100644 --- a/probe.h +++ b/probe.h @@ -38,6 +38,8 @@ void probe_init(); // Returns probe pin state. uint8_t probe_get_state(uint8_t mode); +uint8_t probe_errors_enabled(uint8_t mode); + // Monitors probe pin state and records the system position when detected. Called by the // stepper ISR per ISR tick. void probe_state_monitor(); From 5f1eece67deeb06dc6cdbb969af575edda054066 Mon Sep 17 00:00:00 2001 From: Elijah Insua Date: Mon, 22 Sep 2014 14:35:12 -0700 Subject: [PATCH 13/40] hop over probe pull-off sequence after probe miss and while "no errors" is enabled (G38.3, G38.5) --- motion_control.c | 48 ++++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/motion_control.c b/motion_control.c index 66cb9ac..f4b66cb 100644 --- a/motion_control.c +++ b/motion_control.c @@ -287,7 +287,8 @@ void mc_homing_cycle() // Finish all queued commands and empty planner buffer before starting probe cycle. protocol_buffer_synchronize(); uint8_t auto_start_state = sys.auto_start; // Store run state - + uint8_t perform_pull_off = 1; + // After syncing, check if probe is already triggered. If so, halt and issue alarm. if (probe_get_state(mode) && probe_errors_enabled(mode)) { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); @@ -313,8 +314,13 @@ void mc_homing_cycle() } while ((sys.state != STATE_IDLE) && (sys.state != STATE_QUEUED)); // Probing motion complete. If the probe has not been triggered, error out. - if (sys.probe_state & PROBE_ACTIVE && probe_errors_enabled(mode)) { - bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); + if (sys.probe_state & PROBE_ACTIVE) { + + if (probe_errors_enabled(mode)) { + bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); + } else { + perform_pull_off = 0; + } } protocol_execute_runtime(); // Check and execute run-time commands if (sys.abort) { return; } // Check for system abort @@ -323,24 +329,26 @@ void mc_homing_cycle() st_reset(); // Reest step segment buffer. plan_reset(); // Reset planner buffer. Zero planner positions. Ensure probing motion is cleared. plan_sync_position(); // Sync planner position to current machine position. - - // Pull-off triggered probe to the trigger location since we had to decelerate a little beyond - // it to stop the machine in a controlled manner. - uint8_t idx; - for(idx=0; idx Date: Mon, 22 Sep 2014 14:40:21 -0700 Subject: [PATCH 14/40] add probe_finalize to keep things DRY this allows the PRB report to be valid when in "no errors" mode and the probe fails --- motion_control.c | 1 + probe.c | 10 +++++++--- probe.h | 2 ++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/motion_control.c b/motion_control.c index f4b66cb..f6b7037 100644 --- a/motion_control.c +++ b/motion_control.c @@ -320,6 +320,7 @@ void mc_homing_cycle() bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); } else { perform_pull_off = 0; + probe_finalize(); } } protocol_execute_runtime(); // Check and execute run-time commands diff --git a/probe.c b/probe.c index 7d45fe6..3623f7b 100644 --- a/probe.c +++ b/probe.c @@ -50,6 +50,12 @@ uint8_t probe_errors_enabled(uint8_t mode) { return !(mode & PROBE_NO_ERROR); } +void probe_finalize() { + sys.probe_state = PROBE_OFF; + memcpy(sys.probe_position, sys.position, sizeof(float)*N_AXIS); + bit_true(sys.execute, EXEC_FEED_HOLD); +} + // Monitors probe pin state and records the system position when detected. Called by the // stepper ISR per ISR tick. // NOTE: This function must be extremely efficient as to not bog down the stepper ISR. @@ -57,9 +63,7 @@ void probe_state_monitor() { if (sys.probe_state != PROBE_OFF) { if (probe_get_state(sys.probe_state)) { - sys.probe_state = PROBE_OFF; - memcpy(sys.probe_position, sys.position, sizeof(float)*N_AXIS); - bit_true(sys.execute, EXEC_FEED_HOLD); + probe_finalize(); } } } diff --git a/probe.h b/probe.h index 5a2006d..194e56e 100644 --- a/probe.h +++ b/probe.h @@ -40,6 +40,8 @@ uint8_t probe_get_state(uint8_t mode); uint8_t probe_errors_enabled(uint8_t mode); +void probe_finalize(); + // Monitors probe pin state and records the system position when detected. Called by the // stepper ISR per ISR tick. void probe_state_monitor(); From 297f4d1dd6a3e89b3715b904a8e0209799aaa510 Mon Sep 17 00:00:00 2001 From: Elijah Insua Date: Mon, 22 Sep 2014 20:32:47 -0700 Subject: [PATCH 15/40] report probe_succeeded with probe status --- motion_control.c | 2 +- probe.c | 5 +++-- probe.h | 2 +- report.c | 4 +++- system.h | 1 + 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/motion_control.c b/motion_control.c index f6b7037..79fd30d 100644 --- a/motion_control.c +++ b/motion_control.c @@ -320,7 +320,7 @@ void mc_homing_cycle() bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); } else { perform_pull_off = 0; - probe_finalize(); + probe_finalize(0); } } protocol_execute_runtime(); // Check and execute run-time commands diff --git a/probe.c b/probe.c index 3623f7b..12fcc63 100644 --- a/probe.c +++ b/probe.c @@ -50,8 +50,9 @@ uint8_t probe_errors_enabled(uint8_t mode) { return !(mode & PROBE_NO_ERROR); } -void probe_finalize() { +void probe_finalize(uint8_t probe_succeeded) { sys.probe_state = PROBE_OFF; + sys.probe_succeeded = probe_succeeded; memcpy(sys.probe_position, sys.position, sizeof(float)*N_AXIS); bit_true(sys.execute, EXEC_FEED_HOLD); } @@ -63,7 +64,7 @@ void probe_state_monitor() { if (sys.probe_state != PROBE_OFF) { if (probe_get_state(sys.probe_state)) { - probe_finalize(); + probe_finalize(1); } } } diff --git a/probe.h b/probe.h index 194e56e..17028eb 100644 --- a/probe.h +++ b/probe.h @@ -40,7 +40,7 @@ uint8_t probe_get_state(uint8_t mode); uint8_t probe_errors_enabled(uint8_t mode); -void probe_finalize(); +void probe_finalize(uint8_t probe_succeeded); // Monitors probe pin state and records the system position when detected. Called by the // stepper ISR per ISR tick. diff --git a/report.c b/report.c index 32720eb..ca93efe 100644 --- a/report.c +++ b/report.c @@ -235,7 +235,9 @@ void report_probe_parameters() print_position[i] = sys.probe_position[i]/settings.steps_per_mm[i]; printFloat_CoordValue(print_position[i]); if (i < (N_AXIS-1)) { printPgmString(PSTR(",")); } - } + } + printPgmString(PSTR(":")); + print_uint8_base10(sys.probe_succeeded); printPgmString(PSTR("]\r\n")); } diff --git a/system.h b/system.h index 93ab2b9..3263af8 100644 --- a/system.h +++ b/system.h @@ -79,6 +79,7 @@ typedef struct { uint8_t auto_start; // Planner auto-start flag. Toggled off during feed hold. Defaulted by settings. volatile uint8_t probe_state; // Probing state value. Used to coordinate the probing cycle with stepper ISR. int32_t probe_position[N_AXIS]; // Last probe position in machine coordinates and steps. + uint8_t probe_succeeded; } system_t; extern system_t sys; From 7e67395463b7fedbd0ac2e03aef2e84875d8dcbc Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Wed, 1 Oct 2014 20:22:16 -0600 Subject: [PATCH 16/40] Updated variable spindle and new probing. Minor bug fixes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Minor bug fix for variable spindle PWM output. Values smaller than the minimum RPM for the spindle would overflow the PWM value. Thanks Rob! - Created an optional minimum spindle PWM low-mark value as a compile-time option. This is for special circumstances when the PWM has to be at a certain level to be read by the spindle controller. - Refactored the new probing commands (G38.3, G38.4, G38.5) code to work better with the rest of Grbl’s systems. - Refactored mc_probe() and mc_arc() to accept the mode of the command, i.e. clockwise vs counter, toward vs away, etc. This is to make these functions independent of gcode state variables. - Removed the pull off motion in the probing cycle. This is not an official operation and was added for user simplicity, but wrongly did so. So bye bye. - Created a configure probe invert mask function to handle the different probe pin setting and probing cycle modes with a single mask. - Minor bug fix with reporting motion modes via $G. G38.2 wasn’t showing up. It now does, along with the other new probing commands. - Refactored some of the new pin configurations for the future of Grbl. - --- config.h | 8 ++++- cpu_map.h | 10 +++--- gcode.c | 81 +++++++++++++++++++++++++++++------------------ gcode.h | 9 ++++-- motion_control.c | 69 ++++++++++++++++++---------------------- motion_control.h | 13 +++++--- probe.c | 41 ++++++++++++------------ probe.h | 20 ++++-------- report.c | 16 +++++++--- spindle_control.c | 12 +++++-- system.h | 6 ++-- 11 files changed, 159 insertions(+), 126 deletions(-) diff --git a/config.h b/config.h index b3dcbbd..378ad6a 100644 --- a/config.h +++ b/config.h @@ -156,7 +156,7 @@ // The hardware PWM output on pin D11 is required for variable spindle output voltages. // #define VARIABLE_SPINDLE // Default disabled. Uncomment to enable. -// Use by the variable spindle output only. These parameters set the maximum and minimum spindle speed +// Used by the variable spindle output only. These parameters set the maximum and minimum spindle speed // "S" g-code values to correspond to the maximum and minimum pin voltages. There are 256 discrete and // equally divided voltage bins between the maximum and minimum spindle speeds. So for a 5V pin, 1000 // max rpm, and 250 min rpm, the spindle output voltage would be set for the following "S" commands: @@ -164,6 +164,12 @@ #define SPINDLE_MAX_RPM 1000.0 // Max spindle RPM. This value is equal to 100% duty cycle on the PWM. #define SPINDLE_MIN_RPM 0.0 // Min spindle RPM. This value is equal to (1/256) duty cycle on the PWM. +// Used by variable spindle output only. This forces the PWM output to a minimum duty cycle when enabled. +// When disabled, the PWM pin will still read 0V. Most users will not need this option, but it may be +// useful in certain scenarios. This setting does not update the minimum spindle RPM calculations. Any +// spindle RPM output lower than this value will be set to this value. +// #define MINIMUM_SPINDLE_PWM 5 // Default disabled. Uncomment to enable. Integer (0-255) + // Minimum planner junction speed. Sets the default minimum junction speed the planner plans to at // every buffer block junction, except for starting from rest and end of the buffer, which are always // zero. This value controls how fast the machine moves through junctions with no regard for acceleration diff --git a/cpu_map.h b/cpu_map.h index e918fb2..7295513 100644 --- a/cpu_map.h +++ b/cpu_map.h @@ -206,11 +206,11 @@ // a later date if flash and memory space allows. #define COOLANT_FLOOD_DDR DDRC #define COOLANT_FLOOD_PORT PORTC - #define COOLANT_FLOOD_BIT 4 // Uno Analog Pin 3 + #define COOLANT_FLOOD_BIT 1 // Uno Analog Pin 1 #ifdef ENABLE_M7 // Mist coolant disabled by default. See config.h to enable/disable. #define COOLANT_MIST_DDR DDRC #define COOLANT_MIST_PORT PORTC - #define COOLANT_MIST_BIT 5 // Uno Analog Pin 4 + #define COOLANT_MIST_BIT 2 // Uno Analog Pin 2 #endif // Define user-control pinouts (cycle start, reset, feed hold) input pins. @@ -218,9 +218,9 @@ #define PINOUT_DDR DDRC #define PINOUT_PIN PINC #define PINOUT_PORT PORTC - #define PIN_RESET 1 // Uno Analog Pin 1 - #define PIN_FEED_HOLD 2 // Uno Analog Pin 2 - #define PIN_CYCLE_START 3 // Uno Analog Pin 3 + #define PIN_RESET 3 // Uno Analog Pin 3 + #define PIN_FEED_HOLD 4 // Uno Analog Pin 4 + #define PIN_CYCLE_START 5 // Uno Analog Pin 5 #define PINOUT_INT PCIE1 // Pin change interrupt enable pin #define PINOUT_INT_vect PCINT1_vect #define PINOUT_PCMSK PCMSK1 // Pin change interrupt register diff --git a/gcode.c b/gcode.c index 4afa027..6c482cd 100644 --- a/gcode.c +++ b/gcode.c @@ -123,8 +123,7 @@ uint8_t gc_execute_line(char *line) char letter; float value; uint8_t int_value = 0; - uint16_t mantissa = 0; // NOTE: For mantissa values > 255, variable type must be changed to uint16_t. - uint8_t probe_mode = 0; + uint16_t mantissa = 0; while (line[char_counter] != 0) { // Loop until no more g-code words in line. @@ -210,22 +209,10 @@ uint8_t gc_execute_line(char *line) case 3: gc_block.modal.motion = MOTION_MODE_CCW_ARC; break; // G3 case 38: switch(mantissa) { - case 20: // G38.2 - gc_block.modal.motion = MOTION_MODE_PROBE; - break; - case 30: // G38.3 - gc_block.modal.motion = MOTION_MODE_PROBE; - probe_mode = PROBE_NO_ERROR; - break; - case 40: // G38.4 - gc_block.modal.motion = MOTION_MODE_PROBE; - probe_mode = PROBE_AWAY; - break; - case 50: // G38.5 - gc_block.modal.motion = MOTION_MODE_PROBE; - probe_mode = PROBE_AWAY | PROBE_NO_ERROR; - break; - + case 20: gc_block.modal.motion = MOTION_MODE_PROBE_TOWARD; break; // G38.2 + case 30: gc_block.modal.motion = MOTION_MODE_PROBE_TOWARD_NO_ERROR; break; // G38.3 + case 40: gc_block.modal.motion = MOTION_MODE_PROBE_AWAY; break; // G38.4 + case 50: gc_block.modal.motion = MOTION_MODE_PROBE_AWAY_NO_ERROR; break; // G38.5 default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported G38.x command] } mantissa = 0; // Set to zero to indicate valid non-integer G command. @@ -811,7 +798,8 @@ uint8_t gc_execute_line(char *line) } } break; - case MOTION_MODE_PROBE: + case MOTION_MODE_PROBE_TOWARD: case MOTION_MODE_PROBE_TOWARD_NO_ERROR: + case MOTION_MODE_PROBE_AWAY: case MOTION_MODE_PROBE_AWAY_NO_ERROR: // [G38 Errors]: Target is same current. No axis words. Cutter compensation is enabled. Feed rate // is undefined. Probe is triggered. NOTE: Probe check moved to probe cycle. Instead of returning // an error, it issues an alarm to prevent further motion to the probe. It's also done there to @@ -838,6 +826,9 @@ uint8_t gc_execute_line(char *line) need to update the state and execute the block according to the order-of-execution. */ + // [0. Non-specific/common error-checks and miscellaneous setup]: + gc_state.line_number = gc_block.values.n; + // [1. Comments feedback ]: NOT SUPPORTED // [2. Set feed rate mode ]: @@ -923,13 +914,13 @@ uint8_t gc_execute_line(char *line) // and absolute and incremental modes. if (axis_command) { #ifdef USE_LINE_NUMBERS - mc_line(gc_block.values.xyz, -1.0, false, gc_block.values.n); + mc_line(gc_block.values.xyz, -1.0, false, gc_state.line_number); #else mc_line(gc_block.values.xyz, -1.0, false); #endif } #ifdef USE_LINE_NUMBERS - mc_line(parameter_data, -1.0, false, gc_block.values.n); + mc_line(parameter_data, -1.0, false, gc_state.line_number); #else mc_line(parameter_data, -1.0, false); #endif @@ -959,41 +950,71 @@ uint8_t gc_execute_line(char *line) switch (gc_state.modal.motion) { case MOTION_MODE_SEEK: #ifdef USE_LINE_NUMBERS - mc_line(gc_block.values.xyz, -1.0, false, gc_block.values.n); + mc_line(gc_block.values.xyz, -1.0, false, gc_state.line_number); #else mc_line(gc_block.values.xyz, -1.0, false); #endif break; case MOTION_MODE_LINEAR: #ifdef USE_LINE_NUMBERS - mc_line(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, gc_block.values.n); + mc_line(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, gc_state.line_number); #else mc_line(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate); #endif break; - case MOTION_MODE_CW_ARC: case MOTION_MODE_CCW_ARC: + case MOTION_MODE_CW_ARC: #ifdef USE_LINE_NUMBERS mc_arc(gc_state.position, gc_block.values.xyz, gc_block.values.ijk, gc_block.values.r, - gc_state.feed_rate, gc_state.modal.feed_rate, axis_0, axis_1, axis_linear, gc_block.values.n); + gc_state.feed_rate, gc_state.modal.feed_rate, axis_0, axis_1, axis_linear, true, gc_state.line_number); #else mc_arc(gc_state.position, gc_block.values.xyz, gc_block.values.ijk, gc_block.values.r, - gc_state.feed_rate, gc_state.modal.feed_rate, axis_0, axis_1, axis_linear); + gc_state.feed_rate, gc_state.modal.feed_rate, axis_0, axis_1, axis_linear, true); + #endif + break; + case MOTION_MODE_CCW_ARC: + #ifdef USE_LINE_NUMBERS + mc_arc(gc_state.position, gc_block.values.xyz, gc_block.values.ijk, gc_block.values.r, + gc_state.feed_rate, gc_state.modal.feed_rate, axis_0, axis_1, axis_linear, false, gc_state.line_number); + #else + mc_arc(gc_state.position, gc_block.values.xyz, gc_block.values.ijk, gc_block.values.r, + gc_state.feed_rate, gc_state.modal.feed_rate, axis_0, axis_1, axis_linear, false); #endif break; - case MOTION_MODE_PROBE: + case MOTION_MODE_PROBE_TOWARD: // NOTE: gc_block.values.xyz is returned from mc_probe_cycle with the updated position value. So // upon a successful probing cycle, the machine position and the returned value should be the same. #ifdef USE_LINE_NUMBERS - mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, probe_mode, gc_block.values.n); + mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, false, false, gc_state.line_number); #else - mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, probe_mode); + mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, false, false); + #endif + break; + case MOTION_MODE_PROBE_TOWARD_NO_ERROR: + #ifdef USE_LINE_NUMBERS + mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, false, true, gc_state.line_number); + #else + mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, false, true); + #endif + break; + case MOTION_MODE_PROBE_AWAY: + #ifdef USE_LINE_NUMBERS + mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, true, false, gc_state.line_number); + #else + mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, true, false); + #endif + break; + case MOTION_MODE_PROBE_AWAY_NO_ERROR: + #ifdef USE_LINE_NUMBERS + mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, true, true, gc_state.line_number); + #else + mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, true, true); #endif } // As far as the parser is concerned, the position is now == target. In reality the // motion control system might still be processing the action and the real tool position // in any intermediate location. - memcpy(gc_state.position, gc_block.values.xyz, sizeof(gc_block.values.xyz)); // gc.position[] = target[]; + memcpy(gc_state.position, gc_block.values.xyz, sizeof(gc_block.values.xyz)); // gc_state.position[] = gc_block.values.xyz[] } } diff --git a/gcode.h b/gcode.h index 0e196a9..88a5384 100644 --- a/gcode.h +++ b/gcode.h @@ -71,8 +71,11 @@ #define MOTION_MODE_LINEAR 1 // G1 #define MOTION_MODE_CW_ARC 2 // G2 #define MOTION_MODE_CCW_ARC 3 // G3 -#define MOTION_MODE_PROBE 4 // G38.2, G38.3, G38.4, G38.5 -#define MOTION_MODE_NONE 5 // G80 +#define MOTION_MODE_PROBE_TOWARD 4 // G38.2 +#define MOTION_MODE_PROBE_TOWARD_NO_ERROR 5 // G38.3 +#define MOTION_MODE_PROBE_AWAY 6 // G38.4 +#define MOTION_MODE_PROBE_AWAY_NO_ERROR 7 // G38.5 +#define MOTION_MODE_NONE 8 // G80 // Modal Group G2: Plane select #define PLANE_SELECT_XY 0 // G17 (Default: Must be zero) @@ -164,7 +167,7 @@ typedef struct { float spindle_speed; // RPM float feed_rate; // Millimeters/min uint8_t tool; // Tracks tool number. NOT USED. -// int32_t line_number; // Last line number sent + int32_t line_number; // Last line number sent float position[N_AXIS]; // Where the interpreter considers the tool to be at this point in the code diff --git a/motion_control.c b/motion_control.c index ed62d33..dbefe89 100644 --- a/motion_control.c +++ b/motion_control.c @@ -95,7 +95,7 @@ // 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 +// offset == offset from current xyz, axis_X defines circle plane in tool space, axis_linear is // the direction of helical travel, radius == circle radius, isclockwise boolean. Used // for vector transformation direction. // The arc is approximated by generating a huge number of tiny, linear segments. The chordal tolerance @@ -103,10 +103,10 @@ // distance from segment to the circle when the end points both lie on the circle. #ifdef USE_LINE_NUMBERS void mc_arc(float *position, float *target, float *offset, float radius, float feed_rate, - uint8_t invert_feed_rate, uint8_t axis_0, uint8_t axis_1, uint8_t axis_linear, int32_t line_number) + uint8_t invert_feed_rate, uint8_t axis_0, uint8_t axis_1, uint8_t axis_linear, uint8_t is_clockwise_arc, int32_t line_number) #else void mc_arc(float *position, float *target, float *offset, float radius, float feed_rate, - uint8_t invert_feed_rate, uint8_t axis_0, uint8_t axis_1, uint8_t axis_linear) + uint8_t invert_feed_rate, uint8_t axis_0, uint8_t axis_1, uint8_t axis_linear, uint8_t is_clockwise_arc) #endif { float center_axis0 = position[axis_0] + offset[axis_0]; @@ -118,7 +118,7 @@ // 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 (gc_state.modal.motion == MOTION_MODE_CW_ARC) { // Correct atan2 output per direction + if (is_clockwise_arc) { // Correct atan2 output per direction if (angular_travel >= 0) { angular_travel -= 2*M_PI; } } else { if (angular_travel <= 0) { angular_travel += 2*M_PI; } @@ -287,9 +287,11 @@ void mc_homing_cycle() // Perform tool length probe cycle. Requires probe switch. // NOTE: Upon probe failure, the program will be stopped and placed into ALARM state. #ifdef USE_LINE_NUMBERS - void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, uint8_t mode, int32_t line_number) + void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, uint8_t is_probe_away, + uint8_t is_no_error, int32_t line_number) #else - void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, uint8_t mode) + void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, uint8_t is_probe_away, + uint8_t is_no_error) #endif { // TODO: Need to update this cycle so it obeys a non-auto cycle start. @@ -298,10 +300,14 @@ void mc_homing_cycle() // Finish all queued commands and empty planner buffer before starting probe cycle. protocol_buffer_synchronize(); uint8_t auto_start_state = sys.auto_start; // Store run state - uint8_t perform_pull_off = 1; + // Initialize probing control variables + sys.probe_succeeded = false; // Re-initialize probe history before beginning cycle. + probe_configure_invert_mask(is_probe_away); + // After syncing, check if probe is already triggered. If so, halt and issue alarm. - if (probe_get_state(mode) && probe_errors_enabled(mode)) { + // NOTE: This probe initialization error applies to all probing cycles. + if ( probe_get_state() ) { // Check probe pin state. bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); protocol_execute_runtime(); } @@ -314,8 +320,8 @@ void mc_homing_cycle() mc_line(target, feed_rate, invert_feed_rate); #endif - // Activate the probing monitor in the stepper module. - sys.probe_state = PROBE_ACTIVE | mode; + // Activate the probing state monitor in the stepper module. + sys.probe_state = PROBE_ACTIVE; // Perform probing cycle. Wait here until probe is triggered or motion completes. bit_true_atomic(sys.execute, EXEC_CYCLE_START); @@ -323,17 +329,17 @@ void mc_homing_cycle() protocol_execute_runtime(); if (sys.abort) { return; } // Check for system abort } while ((sys.state != STATE_IDLE) && (sys.state != STATE_QUEUED)); - - // Probing motion complete. If the probe has not been triggered, error out. - if (sys.probe_state & PROBE_ACTIVE) { - - if (probe_errors_enabled(mode)) { - bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); - } else { - perform_pull_off = 0; - probe_finalize(0); - } + + // Probing cycle complete! + + // Set state variables and error out, if the probe failed and cycle with error is enabled. + if (sys.probe_state == PROBE_ACTIVE) { + if (is_no_error) { memcpy(sys.probe_position, sys.position, sizeof(float)*N_AXIS); } + else { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); } + } else { + sys.probe_succeeded = true; // Indicate to system the probing cycle completed successfully. } + sys.probe_state = PROBE_OFF; // Ensure probe state monitor is disabled. protocol_execute_runtime(); // Check and execute run-time commands if (sys.abort) { return; } // Check for system abort @@ -342,24 +348,11 @@ void mc_homing_cycle() plan_reset(); // Reset planner buffer. Zero planner positions. Ensure probing motion is cleared. plan_sync_position(); // Sync planner position to current machine position. - if (perform_pull_off) { - // Pull-off triggered probe to the trigger location since we had to decelerate a little beyond - // it to stop the machine in a controlled manner. - uint8_t idx; - for(idx=0; idx> PROBE_AWAY_BIT) & 1) << PROBE_BIT; - return mode ^ ((PROBE_PIN & PROBE_MASK) ^ probe_invert_mask); -} +uint8_t probe_get_state() { return((PROBE_PIN & PROBE_MASK) ^ probe_invert_mask); } -uint8_t probe_errors_enabled(uint8_t mode) { - return !(mode & PROBE_NO_ERROR); -} - -void probe_finalize(uint8_t probe_succeeded) { - sys.probe_state = PROBE_OFF; - sys.probe_succeeded = probe_succeeded; - memcpy(sys.probe_position, sys.position, sizeof(float)*N_AXIS); - bit_true(sys.execute, EXEC_FEED_HOLD); -} // Monitors probe pin state and records the system position when detected. Called by the // stepper ISR per ISR tick. // NOTE: This function must be extremely efficient as to not bog down the stepper ISR. void probe_state_monitor() { - if (sys.probe_state != PROBE_OFF) { - if (probe_get_state(sys.probe_state)) { - probe_finalize(1); + if (sys.probe_state == PROBE_ACTIVE) { + if (probe_get_state()) { + sys.probe_state = PROBE_OFF; + memcpy(sys.probe_position, sys.position, sizeof(float)*N_AXIS); + bit_true(sys.execute, EXEC_FEED_HOLD); } } } diff --git a/probe.h b/probe.h index 17028eb..968d7ec 100644 --- a/probe.h +++ b/probe.h @@ -22,25 +22,19 @@ #define probe_h // Values that define the probing state machine. -#define PROBE_OFF 0 // No probing. (Must be zero.) +#define PROBE_OFF 0 // Probing disabled or not in use. (Must be zero.) #define PROBE_ACTIVE 1 // Actively watching the input pin. -// Probe direction and error modes -#define PROBE_AWAY 2 // G38.4, G38.5 -#define PROBE_NO_ERROR 4 // G38.3, G38.5 - -#define PROBE_AWAY_BIT 1 -#define PROBE_NO_ERROR_BIT 2 - // Probe pin initialization routine. void probe_init(); -// Returns probe pin state. -uint8_t probe_get_state(uint8_t mode); +// Called by probe_init() and the mc_probe() routines. Sets up the probe pin invert mask to +// appropriately set the pin logic according to setting for normal-high/normal-low operation +// and the probing cycle modes for toward-workpiece/away-from-workpiece. +void probe_configure_invert_mask(uint8_t is_probe_away); -uint8_t probe_errors_enabled(uint8_t mode); - -void probe_finalize(uint8_t probe_succeeded); +// Returns probe pin state. Triggered = true. Called by gcode parser and probe state monitor. +uint8_t probe_get_state(); // Monitors probe pin state and records the system position when detected. Called by the // stepper ISR per ISR tick. diff --git a/report.c b/report.c index 9235f37..58f01d0 100644 --- a/report.c +++ b/report.c @@ -281,12 +281,18 @@ void report_ngc_parameters() // Print current gcode parser mode state void report_gcode_modes() { + printPgmString(PSTR("[")); + switch (gc_state.modal.motion) { - case MOTION_MODE_SEEK : printPgmString(PSTR("[G0")); break; - case MOTION_MODE_LINEAR : printPgmString(PSTR("[G1")); break; - case MOTION_MODE_CW_ARC : printPgmString(PSTR("[G2")); break; - case MOTION_MODE_CCW_ARC : printPgmString(PSTR("[G3")); break; - case MOTION_MODE_NONE : printPgmString(PSTR("[G80")); break; + case MOTION_MODE_SEEK : printPgmString(PSTR("G0")); break; + case MOTION_MODE_LINEAR : printPgmString(PSTR("G1")); break; + case MOTION_MODE_CW_ARC : printPgmString(PSTR("G2")); break; + case MOTION_MODE_CCW_ARC : printPgmString(PSTR("G3")); break; + case MOTION_MODE_PROBE_TOWARD : printPgmString(PSTR("G38.2")); break; + case MOTION_MODE_PROBE_TOWARD_NO_ERROR : printPgmString(PSTR("G38.3")); break; + case MOTION_MODE_PROBE_AWAY : printPgmString(PSTR("G38.4")); break; + case MOTION_MODE_PROBE_AWAY_NO_ERROR : printPgmString(PSTR("G38.5")); break; + case MOTION_MODE_NONE : printPgmString(PSTR("G80")); break; } printPgmString(PSTR(" G")); diff --git a/spindle_control.c b/spindle_control.c index b841084..de773ee 100644 --- a/spindle_control.c +++ b/spindle_control.c @@ -86,10 +86,16 @@ void spindle_run(uint8_t direction, float rpm) #define SPINDLE_RPM_RANGE (SPINDLE_MAX_RPM-SPINDLE_MIN_RPM) TCCRA_REGISTER = (1< SPINDLE_RPM_RANGE ) { rpm = SPINDLE_RPM_RANGE; } // Prevent uint8 overflow + if ( rpm < SPINDLE_MIN_RPM ) { rpm = 0; } + else { + rpm -= SPINDLE_MIN_RPM; + if ( rpm > SPINDLE_RPM_RANGE ) { rpm = SPINDLE_RPM_RANGE; } // Prevent uint8 overflow + } uint8_t current_pwm = floor( rpm*(255.0/SPINDLE_RPM_RANGE) + 0.5); - OCR_REGISTER = current_pwm; + #ifdef MINIMUM_SPINDLE_PWM + if (current_pwm < MINIMUM_SPINDLE_PWM) { current_pwm = MINIMUM_SPINDLE_PWM; } + #endif + OCR_REGISTER = current_pwm; // Set PWM pin output #ifndef CPU_MAP_ATMEGA328P // On the Uno, spindle enable and PWM are shared. SPINDLE_ENABLE_PORT |= (1< Date: Wed, 14 Jan 2015 22:14:52 -0700 Subject: [PATCH 17/40] Lot of refactoring for the future. CoreXY support. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rudimentary CoreXY kinematics support. Didn’t test, but homing and feed holds should work. See config.h. Please report successes and issues as we find bugs. - G40 (disable cutter comp) is now “supported”. Meaning that Grbl will no longer issue an error when typically sent in g-code program header. - Refactored coolant and spindle state setting into separate functions for future features. - Configuration option for fixing homing behavior when there are two limit switches on the same axis sharing an input pin. - Created a new “grbl.h” that will eventually be used as the main include file for Grbl. Also will help simply uploading through the Arduino IDE - Separated out the alarms execution flags from the realtime (used be called runtime) execution flag variable. Now reports exactly what caused the alarm. Expandable for new alarms later on. - Refactored the homing cycle to support CoreXY. - Applied @EliteEng updates to Mega2560 support. Some pins were reconfigured. - Created a central step to position and vice versa function. Needed for non-traditional cartesian machines. Should make it easier later. - Removed the new CPU map for the Uno. No longer going to used. There will be only one configuration to keep things uniform. --- config.h | 27 +- coolant_control.c | 16 +- coolant_control.h | 3 +- cpu_map.h | 174 +- defaults.h | 2 +- gcode.c | 34 +- gcode.h | 43 +- grbl.h | 49 + limits.c | 139 +- limits.h | 2 +- main.c | 5 +- motion_control.c | 66 +- motion_control.h | 2 +- nuts_bolts.c | 2 +- nuts_bolts.h | 14 +- planner.c | 53 +- planner.h | 2 +- print.c | 2 +- print.h | 2 +- probe.c | 4 +- probe.h | 2 +- protocol.c | 93 +- protocol.h | 6 +- report.c | 19 +- report.h | 9 +- serial.c | 14 +- serial.h | 2 +- settings.c | 4 +- settings.h | 6 +- spindle_control.c | 41 +- spindle_control.h | 4 +- stepper.c | 8 +- stepper.h | 8 +- system.c | 67 +- system.h | 36 +- test/gcode/8x_gear_test.nc | 4919 ------------------------------ test/gcode/HSM_test.nc | 1758 ----------- test/gcode/SO2_helloworld.nc | 773 ----- test/gcode/braid_cut2d.nc | 2517 --------------- test/matlab/grbl_sim.m | 437 --- test/matlab/matlab.gcode | 2362 -------------- test/matlab/matlab_convert.py | 270 -- test/matlab/test.gcode | 2363 -------------- test/settings/kikigey89.settings | 31 - test/test.py | 25 - 45 files changed, 529 insertions(+), 15886 deletions(-) create mode 100644 grbl.h delete mode 100644 test/gcode/8x_gear_test.nc delete mode 100644 test/gcode/HSM_test.nc delete mode 100644 test/gcode/SO2_helloworld.nc delete mode 100644 test/gcode/braid_cut2d.nc delete mode 100644 test/matlab/grbl_sim.m delete mode 100644 test/matlab/matlab.gcode delete mode 100755 test/matlab/matlab_convert.py delete mode 100644 test/matlab/test.gcode delete mode 100644 test/settings/kikigey89.settings delete mode 100644 test/test.py diff --git a/config.h b/config.h index 378ad6a..60d240b 100644 --- a/config.h +++ b/config.h @@ -2,7 +2,7 @@ config.h - compile time configuration Part of Grbl v0.9 - Copyright (c) 2013-2014 Sungeun K. Jeon + Copyright (c) 2013-2015 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 @@ -43,9 +43,9 @@ // Default cpu mappings. Grbl officially supports the Arduino Uno only. Other processor types // may exist from user-supplied templates or directly user-defined in cpu_map.h -#define CPU_MAP_ATMEGA328P_TRADITIONAL // Arduino Uno CPU +#define CPU_MAP_ATMEGA328P // Arduino Uno CPU -// Define runtime command special characters. These characters are 'picked-off' directly from the +// Define realtime command special characters. These characters are 'picked-off' directly from the // serial read data stream and are not passed to the grbl line execution parser. Select characters // that do not and must not exist in the streamed g-code program. ASCII control characters may be // used, if they are available per user setup. Also, extended ASCII codes (>127), which are never in @@ -107,6 +107,14 @@ #define N_DECIMAL_RATEVALUE_MM 0 // Rate or velocity value in mm/min #define N_DECIMAL_SETTINGVALUE 3 // Decimals for floating point setting values +// If your machine has two limits switches wired in parallel to one axis, you will need to enable +// this feature. Since the two switches are sharing a single pin, there is no way for Grbl to tell +// which one is enabled. This option only effects homing, where if a limit is engaged, Grbl will +// alarm out and force the user to manually disengage the limit switch. Otherwise, if you have one +// limit switch for each axis, don't enable this option. By keeping it disabled, you can homing while +// on the limit switch and not have to move the machine off of it. +// #define LIMITS_TWO_SWITCHES_ON_AXES + // Allows GRBL to track and report gcode line numbers. Enabling this means that the planning buffer // goes from 18 or 16 to make room for the additional line number data in the plan_block_t struct // #define USE_LINE_NUMBERS // Disabled by default. Uncomment to enable. @@ -126,6 +134,15 @@ // NOTE: The M8 flood coolant control pin on analog pin 4 will still be functional regardless. // #define ENABLE_M7 // Disabled by default. Uncomment to enable. +// Enable CoreXY kinematics. Use ONLY with CoreXY machines. +// IMPORTANT: If homing is enabled, you must reconfigure the homing cycle #defines above to +// #define HOMING_CYCLE_0 (1< 255) -// #error Parameters ACCELERATION_TICKS / ISR_TICKS must be < 256 to prevent integer overflow. -// #endif + // --------------------------------------------------------------------------------------- diff --git a/coolant_control.c b/coolant_control.c index 9f629ce..d8336d5 100644 --- a/coolant_control.c +++ b/coolant_control.c @@ -2,7 +2,7 @@ coolant_control.c - coolant control methods Part of Grbl v0.9 - Copyright (c) 2012-2014 Sungeun K. Jeon + Copyright (c) 2012-2015 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 @@ -43,12 +43,8 @@ void coolant_stop() } -void coolant_run(uint8_t mode) +void coolant_set_state(uint8_t mode) { - if (sys.state == STATE_CHECK_MODE) { return; } - - protocol_auto_cycle_start(); //temp fix for M8 lockup - protocol_buffer_synchronize(); // Ensure coolant turns on when specified in program. if (mode == COOLANT_FLOOD_ENABLE) { COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT); @@ -61,3 +57,11 @@ void coolant_run(uint8_t mode) coolant_stop(); } } + + +void coolant_run(uint8_t mode) +{ + if (sys.state == STATE_CHECK_MODE) { return; } + protocol_buffer_synchronize(); // Ensure coolant turns on when specified in program. + coolant_set_state(mode); +} diff --git a/coolant_control.h b/coolant_control.h index db3c71c..f093cee 100644 --- a/coolant_control.h +++ b/coolant_control.h @@ -2,7 +2,7 @@ coolant_control.h - spindle control methods Part of Grbl v0.9 - Copyright (c) 2012-2014 Sungeun K. Jeon + Copyright (c) 2012-2015 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 @@ -24,6 +24,7 @@ void coolant_init(); void coolant_stop(); +void coolant_set_state(uint8_t mode); void coolant_run(uint8_t mode); #endif \ No newline at end of file diff --git a/cpu_map.h b/cpu_map.h index 7295513..3e46c30 100644 --- a/cpu_map.h +++ b/cpu_map.h @@ -2,7 +2,7 @@ cpu_map.h - CPU and pin mapping configuration file Part of Grbl v0.9 - Copyright (c) 2012-2014 Sungeun K. Jeon + Copyright (c) 2012-2015 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 @@ -31,7 +31,7 @@ //---------------------------------------------------------------------------------------- -#ifdef CPU_MAP_ATMEGA328P_TRADITIONAL // (Arduino Uno) Officially supported by Grbl. +#ifdef CPU_MAP_ATMEGA328P // (Arduino Uno) Officially supported by Grbl. // Define serial port pins and interrupt vectors. #define SERIAL_RX USART_RX_vect @@ -123,6 +123,7 @@ #ifdef VARIABLE_SPINDLE // Advanced Configuration Below You should not need to touch these variables + #define PWM_MAX_VALUE 255.0 #define TCCRA_REGISTER TCCR2A #define TCCRB_REGISTER TCCR2B #define OCR_REGISTER OCR2A @@ -142,118 +143,6 @@ #endif -//---------------------------------------------------------------------------------------- - -#ifdef CPU_MAP_ATMEGA328P_NEW // (Arduino Uno) New test pinout configuration. Still subject to change. Not finalized! - - // Define serial port pins and interrupt vectors. - #define SERIAL_RX USART_RX_vect - #define SERIAL_UDRE USART_UDRE_vect - - // Define step pulse output pins. NOTE: All step bit pins must be on the same port. - #define STEP_DDR DDRD - #define STEP_PORT PORTD - #define X_STEP_BIT 2 // Uno Digital Pin 2 - #define Y_STEP_BIT 3 // Uno Digital Pin 3 - #define Z_STEP_BIT 4 // Uno Digital Pin 4 - #define STEP_MASK ((1<. +*/ + +// NOTE: This is not used by the 'make' compiling method. This is currently only used for +// simplifying compiling through the Arduino IDE at the moment. However, it may eventually +// turn into a central include file for the overall system. + +#ifndef grbl_h +#define grbl_h + +// All of the Grbl system include files. +#include "config.h" +#include "coolant_control.h" +#include "cpu_map.h" +#include "defaults.h" +#include "eeprom.h" +#include "gcode.h" +#include "limits.h" +#include "motion_control.h" +#include "nuts_bolts.h" +#include "planner.h" +#include "print.h" +#include "probe.h" +#include "protocol.h" +#include "report.h" +#include "serial.h" +#include "settings.h" +#include "spindle_control.h" +#include "stepper.h" +#include "system.h" + +#endif diff --git a/limits.c b/limits.c index 4538dcb..9cb43c4 100644 --- a/limits.c +++ b/limits.c @@ -2,7 +2,7 @@ limits.c - code pertaining to limit-switches and performing the homing cycle Part of Grbl v0.9 - Copyright (c) 2012-2014 Sungeun K. Jeon + Copyright (c) 2012-2015 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 @@ -89,9 +89,9 @@ void limits_disable() // locked out until a homing cycle or a kill lock command. Allows the user to disable the hard // limit setting if their limits are constantly triggering after a reset and move their axes. if (sys.state != STATE_ALARM) { - if (bit_isfalse(sys.execute,EXEC_ALARM)) { + if (!(sys.rt_exec_alarm)) { mc_reset(); // Initiate system kill. - bit_true_atomic(sys.execute, (EXEC_ALARM | EXEC_CRIT_EVENT)); // Indicate hard limit critical event + bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event } } } @@ -102,13 +102,13 @@ void limits_disable() { WDTCSR &= ~(1< settings.max_travel[idx]) { max_travel = settings.max_travel[idx]; } @@ -148,6 +151,7 @@ void limits_go_home(uint8_t cycle_mask) max_travel *= -HOMING_AXIS_SEARCH_SCALAR; // Ensure homing switches engaged by over-estimating max travel. plan_reset(); // Reset planner buffer to zero planner current position and to clear previous motions. + plan_sync_position(); // Sync planner position to current machine position. do { // Initialize invert_pin boolean based on approach and invert pin user setting. @@ -157,20 +161,23 @@ void limits_go_home(uint8_t cycle_mask) // Initialize and declare variables needed for homing routine. uint8_t n_active_axis = 0; uint8_t axislock = 0; - + + system_convert_array_steps_to_mpos(target,sys.position); for (idx=0; idx 0.0) { + for (idx=0; idx 0) { - // NOTE: Check and execute runtime commands during dwell every <= DWELL_TIME_STEP milliseconds. - protocol_execute_runtime(); + // NOTE: Check and execute realtime commands during dwell every <= DWELL_TIME_STEP milliseconds. + protocol_execute_realtime(); if (sys.abort) { return; } _delay_ms(DWELL_TIME_STEP); // Delay DWELL_TIME_STEP increment } @@ -243,15 +244,16 @@ void mc_homing_cycle() // Check and abort homing cycle, if hard limits are already enabled. Helps prevent problems // with machines with limits wired on both ends of travel to one limit pin. // TODO: Move the pin-specific LIMIT_PIN call to limits.c as a function. - uint8_t limit_state = (LIMIT_PIN & LIMIT_MASK); - if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { limit_state ^= LIMIT_MASK; } - if (limit_state) { - mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown. - bit_true_atomic(sys.execute, (EXEC_ALARM | EXEC_CRIT_EVENT)); // Indicate homing limit critical event - return; - } - - sys.state = STATE_HOMING; // Set system state variable + #ifdef LIMITS_TWO_SWITCHES_ON_AXES + uint8_t limit_state = (LIMIT_PIN & LIMIT_MASK); + if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { limit_state ^= LIMIT_MASK; } + if (limit_state) { + mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown. + bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); + return; + } + #endif + limits_disable(); // Disable hard limits pin change register for cycle duration // ------------------------------------------------------------------------------------- @@ -266,7 +268,7 @@ void mc_homing_cycle() limits_go_home(HOMING_CYCLE_2); // Homing cycle 2 #endif - protocol_execute_runtime(); // Check for reset and set system abort. + protocol_execute_realtime(); // Check for reset and set system abort. if (sys.abort) { return; } // Did not complete. Alarm state set by mc_alarm. // Homing cycle complete! Setup system for normal operation. @@ -275,10 +277,6 @@ void mc_homing_cycle() // Gcode parser position was circumvented by the limits_go_home() routine, so sync position now. gc_sync_position(); - // Set idle state after homing completes and before returning to main program. - sys.state = STATE_IDLE; - st_go_idle(); // Set idle state after homing completes - // If hard limits feature enabled, re-enable hard limits pin change register after homing cycle. limits_init(); } @@ -308,8 +306,8 @@ void mc_homing_cycle() // After syncing, check if probe is already triggered. If so, halt and issue alarm. // NOTE: This probe initialization error applies to all probing cycles. if ( probe_get_state() ) { // Check probe pin state. - bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); - protocol_execute_runtime(); + bit_true_atomic(sys.rt_exec_alarm, EXEC_ALARM_PROBE_FAIL); + protocol_execute_realtime(); } if (sys.abort) { return; } // Return if system reset has been issued. @@ -324,9 +322,9 @@ void mc_homing_cycle() sys.probe_state = PROBE_ACTIVE; // Perform probing cycle. Wait here until probe is triggered or motion completes. - bit_true_atomic(sys.execute, EXEC_CYCLE_START); + bit_true_atomic(sys.rt_exec_state, EXEC_CYCLE_START); do { - protocol_execute_runtime(); + protocol_execute_realtime(); if (sys.abort) { return; } // Check for system abort } while ((sys.state != STATE_IDLE) && (sys.state != STATE_QUEUED)); @@ -335,12 +333,12 @@ void mc_homing_cycle() // Set state variables and error out, if the probe failed and cycle with error is enabled. if (sys.probe_state == PROBE_ACTIVE) { if (is_no_error) { memcpy(sys.probe_position, sys.position, sizeof(float)*N_AXIS); } - else { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); } + else { bit_true_atomic(sys.rt_exec_alarm, EXEC_ALARM_PROBE_FAIL); } } else { sys.probe_succeeded = true; // Indicate to system the probing cycle completed successfully. } sys.probe_state = PROBE_OFF; // Ensure probe state monitor is disabled. - protocol_execute_runtime(); // Check and execute run-time commands + protocol_execute_realtime(); // Check and execute run-time commands if (sys.abort) { return; } // Check for system abort // Reset the stepper and planner buffers to remove the remainder of the probe motion. @@ -349,13 +347,11 @@ void mc_homing_cycle() plan_sync_position(); // Sync planner position to current machine position. // TODO: Update the g-code parser code to not require this target calculation but uses a gc_sync_position() call. - uint8_t idx; - for(idx=0; idxsteps[A_MOTOR] = labs((target_steps[X_AXIS]-pl.position[X_AXIS]) - (target_steps[Y_AXIS]-pl.position[Y_AXIS])); + block->steps[B_MOTOR] = labs((target_steps[X_AXIS]-pl.position[X_AXIS]) + (target_steps[Y_AXIS]-pl.position[Y_AXIS])); + #endif + for (idx=0; idxsteps[idx] = labs(target_steps[idx]-pl.position[idx]); - block->step_event_count = max(block->step_event_count, block->steps[idx]); - - // Compute individual axes distance for move and prep unit vector calculations. + // Calculate target position in absolute steps, number of steps for each axis, and determine max step events. + // Also, compute individual axes distance for move and prep unit vector calculations. // NOTE: Computes true distance from converted step values. - delta_mm = (target_steps[idx] - pl.position[idx])/settings.steps_per_mm[idx]; + #ifdef COREXY + if ( !(idx == A_MOTOR) && !(idx == B_MOTOR) ) { + target_steps[idx] = lround(target[idx]*settings.steps_per_mm[idx]); + block->steps[idx] = labs(target_steps[idx]-pl.position[idx]); + } + block->step_event_count = max(block->step_event_count, block->steps[idx]); + if (idx == A_MOTOR) { + delta_mm = ((target_steps[X_AXIS]-pl.position[X_AXIS]) - (target_steps[Y_AXIS]-pl.position[Y_AXIS]))/settings.steps_per_mm[idx]; + } else if (idx == B_MOTOR) { + delta_mm = ((target_steps[X_AXIS]-pl.position[X_AXIS]) + (target_steps[Y_AXIS]-pl.position[Y_AXIS]))/settings.steps_per_mm[idx]; + } else { + delta_mm = (target_steps[idx] - pl.position[idx])/settings.steps_per_mm[idx]; + } + #else + target_steps[idx] = lround(target[idx]*settings.steps_per_mm[idx]); + block->steps[idx] = labs(target_steps[idx]-pl.position[idx]); + block->step_event_count = max(block->step_event_count, block->steps[idx]); + delta_mm = (target_steps[idx] - pl.position[idx])/settings.steps_per_mm[idx]; + #endif unit_vec[idx] = delta_mm; // Store unit vector numerator. Denominator computed later. // Set direction bits. Bit enabled always means direction is negative. @@ -403,9 +422,21 @@ uint8_t plan_check_full_buffer() // Reset the planner position vectors. Called by the system abort/initialization routine. void plan_sync_position() { + // TODO: For motor configurations not in the same coordinate frame as the machine position, + // this function needs to be updated to accomodate the difference. uint8_t idx; for (idx=0; idx SPINDLE_RPM_RANGE ) { rpm = SPINDLE_RPM_RANGE; } // Prevent uint8 overflow + if ( rpm > SPINDLE_RPM_RANGE ) { rpm = SPINDLE_RPM_RANGE; } // Prevent integer overflow } - uint8_t current_pwm = floor( rpm*(255.0/SPINDLE_RPM_RANGE) + 0.5); + current_pwm = floor( rpm*(PWM_MAX_VALUE/SPINDLE_RPM_RANGE) + 0.5); #ifdef MINIMUM_SPINDLE_PWM if (current_pwm < MINIMUM_SPINDLE_PWM) { current_pwm = MINIMUM_SPINDLE_PWM; } #endif OCR_REGISTER = current_pwm; // Set PWM pin output - #ifndef CPU_MAP_ATMEGA328P // On the Uno, spindle enable and PWM are shared. + #ifdef CPU_MAP_ATMEGA2560 // On the Uno, spindle enable and PWM are shared. SPINDLE_ENABLE_PORT |= (1<, this feeds the simulator planner one line motion -% block. The left side is the first block in the buffer and the one that will be executed -% by the stepper module first. The right side is the end of the planner buffer, where the -% most recent streamed block is appended onto the planner buffer. Grbl's planner -% optimizes the velocity profiles between the beginning and end of the buffer based on -% the acceleration limits, intended velocity/feedrate, and line motion junction angles -% with their corresponding velocity limits (i.e. junctions with acute angles needs to come -% to a complete stop vs straight junctions can continue through at full speed.) - -% ---------------------------------------------------------------------------------------- - - -% Main function -% NOTE: This is just a way to keep all functions in one place, but all non-global variables -% are cleared as soon as this script completes. -function main() - -% Load pre-parsed gcode moves. -close all; -warning off; -clearvars -global -fid = fopen('matlab.gcode','r'); -gcode = textscan(fid,'%d8%f32%f32%f32%f32'); -nblock = length(gcode{1}); - -% Plot all g-code moves. -figure -line(gcode{3},gcode{4},gcode{5}); -axis equal; -% axis([min(gcode{3}) max(gcode{3}) min(gcode{4}) max(gcode{4}) min(gcode{5}) max(gcode{5})]); -title('G-code programming line motions'); -view(3); - -% Set up figure for planner queue -figure - -% Print help. -disp(''); -disp(' BLUE line indicates completed planner blocks that require no recalculation.'); -disp(' RED line indicates planner blocks that have been recalculated.'); -disp(' GREEN line indicates the location of the BPLANNED pointer. Always a recalculated block.'); -disp(' BLACK dotted-line and ''x'' indicates block nominal speed and max junction velocity, respectively.'); -disp(' CYAN ''.'' indicates block initial entry speed.'); - -% Define Grbl settings. -BUFFER_SIZE = 18; % Number of planner blocks in its ring buffer. -steps_per_mm = 200; -seekrate = 2500; % mm/min -acceleration = [100 100 100]; % mm/sec^2 [ X Y Z ] axes -junction_deviation = 0.1; % mm. See Grbl documentation on this parameter. -inch_2_mm = 25.4; -ACCELERATION_TICKS_PER_SECOND = 100; - -gcode{2} = gcode{2}; -gcode{2} = inch_2_mm*gcode{2}; -gcode{3} = inch_2_mm*gcode{3}; -gcode{4} = inch_2_mm*gcode{4}; -gcode{5} = inch_2_mm*gcode{5}; - -% Initialize blocks -block.steps = []; -block.step_event_count = []; -block.delta_mm = []; -block.millimeters = []; -block.acceleration = []; -block.speed = []; -block.nominal_speed = []; -block.max_entry_speed = []; -block.entry_speed = []; -block.recalculate_flag = false; -for i = 2:BUFFER_SIZE - block(i) = block(1); -end - -% Initialize planner -position = [0 0 0]; -prev_unit_vec = [0 0 0]; -previous_nominal_speed = 0; -pos = 0; - -% BHEAD and BTAIL act as pointers to the block head and tail. -% BPLANNED acts as a pointer of the location of the end of a completed/optimized plan. -bhead = 1; -btail = 1; -bplanned = 1; - -global block bhead btail bplanned nind acceleration BUFFER_SIZE pos ACCELERATION_TICKS_PER_SECOND - -% Main loop. Simulates plan_buffer_line(). All of the precalculations for the newest incoming -% block occurs here. Anything independent of the planner changes. -for i = 1:nblock - - target = round([gcode{3}(i) gcode{4}(i) gcode{5}(i)].*steps_per_mm); - if gcode{1}(i) == 1 - feedrate = gcode{2}(i); - else - feedrate = seekrate; - end - - nind = next_block_index(bhead); - if nind == btail - % Simulate a constantly full buffer. Move buffer tail. - bind = next_block_index(btail); - % Push planned pointer if encountered. Prevents it from looping back around the ring buffer. - if btail == bplanned; bplanned = bind; end - btail = bind; - end - - block(bhead).steps = abs(target-position); - block(bhead).step_event_count = max(block(bhead).steps); - - % Bail if this is a zero-length block - if block(bhead).step_event_count == 0 - disp(['Zero-length block in line ',int2str(i)]); - else - - % Compute path vector in terms of absolute step target and current positions - delta_mm = single((target-position)./steps_per_mm); - block(bhead).millimeters = single(norm(delta_mm)); - inverse_millimeters = single(1/block(bhead).millimeters); - - % Compute path unit vector - unit_vec = delta_mm/block(bhead).millimeters; - - % Calculate speed in mm/minute for each axis - inverse_minute = single(feedrate * inverse_millimeters); - block(bhead).speed = delta_mm*inverse_minute; - block(bhead).nominal_speed = block(bhead).millimeters*inverse_minute; - - % Calculate block acceleration. Operates on absolute value of unit vector. - [max_acc,ind] = max(abs(unit_vec)./acceleration); % Determine limiting acceleration - block(bhead).acceleration = acceleration(ind)/abs(unit_vec(ind)); - - % Compute maximum junction speed - block(bhead).max_entry_speed = 0.0; - if previous_nominal_speed > 0.0 - cos_theta = dot(-previous_unit_vec,unit_vec); - if (cos_theta < 0.95) - block(bhead).max_entry_speed = min([block(bhead).nominal_speed,previous_nominal_speed]); - if (cos_theta > -0.95) - sin_theta_d2 = sqrt(0.5*(1.0-cos_theta)); - block(bhead).max_entry_speed = min([block(bhead).max_entry_speed,sqrt(block(bhead).acceleration*3600*junction_deviation*sin_theta_d2/(1.0-sin_theta_d2))]); - end - end - end - - block(bhead).entry_speed = 0; % Just initialize. Set accurately in the replanning function. - block(bhead).recalculate_flag = true; % Plotting flag to indicate this block has been updated. - - previous_unit_vec = unit_vec; - previous_nominal_speed = block(bhead).nominal_speed; - position = target; - - bhead = nind; % Block complete. Push buffer pointer. - planner_recalculate(); - - plot_buffer_velocities(); - end -end -return - -% Computes the next block index in the planner ring buffer -function block_index = next_block_index(block_index) -global BUFFER_SIZE - block_index = block_index + 1; - if block_index > BUFFER_SIZE - block_index = 1; - end -return - -% Computes the previous block index in the planner ring buffer -function block_index = prev_block_index(block_index) -global BUFFER_SIZE - block_index = block_index-1; - if block_index < 1 - block_index = BUFFER_SIZE; - end -return - - -% Planner recalculate function. The magic happens here. -function planner_recalculate(block) - - global block bhead btail bplanned acceleration - - bind = prev_block_index(bhead); - if bind == bplanned; return; end % Bail, if only one block in buffer. Can't be operated on. - - % Reverse Pass: Coarsely maximize all possible deceleration curves back-planning from the last - % block in buffer. Cease planning when the last optimal planned or tail pointer is reached. - % NOTE: Forward pass will later refine and correct the reverse pass to create an optimal plan. - next = []; - curr = bind; % Last block in buffer. - - % Calculate maximum entry speed for last block in buffer, where the exit speed is always zero. - block(curr).entry_speed = min([block(curr).max_entry_speed,sqrt(2*block(curr).acceleration*60*60*block(curr).millimeters)]); - - bind = prev_block_index(bind); % Btail or second to last block - if (bind == bplanned) - % Only two plannable blocks in buffer. Reverse pass complete. - % Check if the first block is the tail. If so, notify stepper module to update its current parameters. - % if bind == btail; update_tail_block; end - else - % Three or more plannable blocks in buffer. Loop it. - while bind ~= bplanned % Loop until bplanned point hits. Replans to last plan point. - next = curr; - curr = bind; - bind = prev_block_index( bind ); % Previous block pointer. - - % Check if the first block is the tail. If so, notify stepper module to update its current parameters. - % if bind == btail; update_tail_block; end - - % Compute maximum entry speed decelerating over the current block from its exit speed. - if block(curr).entry_speed ~= block(curr).max_entry_speed - block(curr).recalculate_flag = true; % Plotting flag to indicate this block has been updated. - block(curr).entry_speed = min([ block(curr).max_entry_speed,... - sqrt(block(next).entry_speed^2 + 2*block(curr).acceleration*60*60*block(curr).millimeters)]); - end - - end - end - - % For two blocks, reverse pass is skipped, but forward pass plans second block entry speed - % onward. This prevents the first, or the potentially executing block, from being over-written. - % NOTE: Can never be bhead, since bsafe is always in active buffer. - next = bplanned; - bind = next_block_index(bplanned); % Start at bplanned - while bind ~= bhead - curr = next; - next = bind; - - % An acceleration block is always an optimally planned block since it starts from the first - % block's current speed or a maximum junction speed. Compute accelerations from this block - % and update the next block's entry speed. - if (block(curr).entry_speed < block(next).entry_speed) - % Once speed is set by forward planner, the plan for this block is finished and optimal. - % Increment the planner pointer forward one block. - - entry_speed = sqrt(block(curr).entry_speed^2 + 2*block(curr).acceleration*60*60*block(curr).millimeters); - if (block(next).entry_speed > entry_speed) - block(next).entry_speed = entry_speed; - bplanned = bind; - end - - end - - % Check if the next block entry speed is at max_entry_speed. If so, move the planned pointer, since - % this entry speed cannot be improved anymore and all prior blocks have been completed and optimally planned. - if block(next).entry_speed == block(next).max_entry_speed - bplanned = bind; - end - - % Recalculate trapezoid can be installed here, since it scans through all of the plannable blocks. - % NOTE: Eventually this will only be computed when being executed. - - bind = next_block_index( bind ); - - end - -return - -% ---------------------------------------------------------------------------------------- -% PLOTTING FUNCTIONS - -% Plots the entire buffer plan into a MATLAB figure to visual the plan. -% BLUE line indicates completed planner blocks that require no recalculation. -% RED line indicates planner blocks that have been recalculated. -% GREEN line indicates the location of the BPLANNED pointer. Always a recalculated block. -% BLACK dotted-line and 'x' indicates block nominal speed and max junction velocity, respectively. -% CYAN '.' indicates block initial entry speed. -function plot_buffer_velocities() - global block bhead btail bplanned acceleration pos ACCELERATION_TICKS_PER_SECOND - bind = btail; - curr = []; - next = []; - - pos_initial = 0; - pos = 0; - while bind ~= bhead - curr = next; - next = bind; - hold on; - if ~isempty(curr) - accel_d = estimate_acceleration_distance(block(curr).entry_speed, block(curr).nominal_speed, block(curr).acceleration*60*60); - decel_d = estimate_acceleration_distance(block(curr).nominal_speed, block(next).entry_speed,-block(curr).acceleration*60*60); - plateau_d = block(curr).millimeters-accel_d-decel_d; - if plateau_d < 0 - accel_d = intersection_distance(block(curr).entry_speed, block(next).entry_speed, block(curr).acceleration*60*60, block(curr).millimeters); - if accel_d < 0 - accel_d = 0; - elseif accel_d > block(curr).millimeters - accel_d = block(curr).millimeters; - end - plateau_d = 0; - end - color = 'b'; - if (block(curr).recalculate_flag || block(next).recalculate_flag) - block(curr).recalculate_flag = false; - color = 'r'; - end - if bplanned == curr - color = 'g'; - end - - plot_trap(pos,block(curr).entry_speed,block(next).entry_speed,block(curr).nominal_speed,block(curr).acceleration,accel_d,plateau_d,block(curr).millimeters,color) - plot([pos pos+block(curr).millimeters],block(curr).nominal_speed*[1 1],'k:') % BLACK dotted indicates - plot(pos,block(curr).max_entry_speed,'kx') - - pos = pos + block(curr).millimeters; - plot(pos,block(next).entry_speed,'c.'); - end - bind = next_block_index( bind ); - end - - accel_d = estimate_acceleration_distance(block(next).entry_speed, block(next).nominal_speed, block(next).acceleration*60*60); - decel_d = estimate_acceleration_distance(block(next).nominal_speed, 0, -block(next).acceleration*60*60); - plateau_d = block(next).millimeters-accel_d-decel_d; - if plateau_d < 0 - accel_d = intersection_distance(block(next).entry_speed, 0, block(next).acceleration*60*60, block(next).millimeters); - if accel_d < 0 - accel_d = 0; - elseif accel_d > block(next).millimeters - accel_d = block(next).millimeters; - end - plateau_d = 0; - end - block(next).recalculate_flag = false; - color = 'r'; - if bplanned == next - color= 'g'; - end - - plot_trap(pos,block(next).entry_speed,0,block(next).nominal_speed,block(next).acceleration,accel_d,plateau_d,block(next).millimeters,color) - plot([pos pos+block(next).millimeters],block(next).nominal_speed*[1 1],'k:') - plot(pos,block(next).max_entry_speed,'kx') - - plot(pos,block(next).entry_speed,'.'); - pos = pos + block(next).millimeters; - plot(pos,0,'rx'); - xlabel('mm'); - ylabel('mm/sec'); - xlim([pos_initial pos]) - title('Planner buffer optimized velocity profile'); - pause(); - hold off; - - plot(pos,0) -return - - -function d_a = estimate_acceleration_distance(initial_rate, target_rate, acceleration,rate_delta) - d_a = (target_rate*target_rate-initial_rate*initial_rate)/(2*acceleration); -return - -function d_i = intersection_distance(initial_rate, final_rate, acceleration, distance, rate_delta) - d_i = (2*acceleration*distance-initial_rate*initial_rate+final_rate*final_rate)/(4*acceleration); -return - - -% Simply plots the ac/de-celeration curves and plateaus of a trapezoid. -function plot_trap(pos,initial_rate,final_rate,rate,accel,accel_d,plateau_d,millimeters,color) - - dx = 1.0; % Line segment length - linex = [pos]; liney = [initial_rate]; - - % Acceleration - np = floor(accel_d/dx); - if np - v = initial_rate; - for i = 1:np - v = sqrt(v^2+2*accel*60*60*dx); - linex = [linex pos+i*dx]; - liney = [liney v]; - end - end - - % Plateau - v = sqrt(initial_rate^2 + 2*accel*60*60*accel_d); - if v < rate - rate = v; - end - linex = [linex pos+[accel_d accel_d+plateau_d]]; - liney = [liney [rate rate]]; - - % Deceleration - np = floor((millimeters-accel_d-plateau_d)/dx); - if np - v = rate; - for i = 1:np - v = sqrt(v^2-2*accel*60*60*dx); - linex = [linex pos+i*dx+accel_d+plateau_d]; - liney = [liney v]; - end - end - - linex = [linex pos+millimeters]; - liney = [ liney final_rate]; - plot(linex,liney,color); - -return - - - diff --git a/test/matlab/matlab.gcode b/test/matlab/matlab.gcode deleted file mode 100644 index 8ad9cdc..0000000 --- a/test/matlab/matlab.gcode +++ /dev/null @@ -1,2362 +0,0 @@ -0 0.0 0.0 0.0 0.0 -0 0.0 0.0 0.0 0.0 -0 0.0 0.0 0.0 0.0 -0 0.0 0.0 0.0 6.0 -0 0.0 37.56 12.33 6.0 -1 300.0 37.56 12.33 -1.0 -1 300.0 37.56 0.88 -1.0 -1 300.0 49.01 0.88 -1.0 -1 300.0 49.01 12.33 -1.0 -1 300.0 37.56 12.33 -1.0 -0 300.0 37.56 12.33 6.0 -0 300.0 37.56 0.88 6.0 -1 300.0 37.56 0.88 -1.0 -1 300.0 37.56 -10.57 -1.0 -1 300.0 49.01 -10.57 -1.0 -1 300.0 49.01 0.88 -1.0 -1 300.0 37.56 0.88 -1.0 -0 300.0 37.56 0.88 6.0 -0 300.0 49.01 12.33 6.0 -1 300.0 49.01 12.33 -1.0 -1 300.0 52.08 15.01 -1.0 -0 300.0 52.08 15.01 6.0 -0 300.0 49.01 0.88 6.0 -1 300.0 49.01 0.88 -1.0 -1 300.0 52.08 6.21 -1.0 -1 300.0 52.08 15.01 -1.0 -1 300.0 43.29 15.01 -1.0 -1 300.0 37.56 12.33 -1.0 -0 300.0 37.56 12.33 6.0 -0 300.0 49.01 -10.57 6.0 -1 300.0 49.01 -10.57 -1.0 -1 300.0 52.08 -2.58 -1.0 -1 300.0 52.08 6.21 -1.0 -1 300.0 49.01 0.88 -1.0 -0 300.0 49.01 0.88 6.0 -0 300.0 49.01 0.88 20.0 -0 300.0 0.0 0.0 20.0 -1 300.0 -7.1 -39.88 20.0 -1 300.0 -10.3 -38.12 20.0 -1 300.0 -10.7 -37.9 20.0 -1 300.0 -11.1 -37.68 20.0 -1 300.0 -11.89 -37.23 20.0 -1 300.0 -13.45 -36.36 20.0 -1 300.0 -13.82 -36.14 20.0 -1 300.0 -14.2 -35.92 20.0 -1 300.0 -14.92 -35.48 20.0 -1 300.0 -16.29 -34.63 20.0 -1 300.0 -16.64 -34.4 20.0 -1 300.0 -16.97 -34.16 20.0 -1 300.0 -17.61 -33.71 20.0 -1 300.0 -17.91 -33.49 20.0 -1 300.0 -18.2 -33.26 20.0 -1 300.0 -18.74 -32.82 20.0 -1 300.0 -18.99 -32.6 20.0 -1 300.0 -19.23 -32.39 20.0 -1 300.0 -19.45 -32.17 20.0 -1 300.0 -19.65 -31.96 20.0 -1 300.0 -19.84 -31.75 20.0 -1 300.0 -20.02 -31.54 20.0 -1 300.0 -20.18 -31.34 20.0 -1 300.0 -20.32 -31.13 20.0 -1 300.0 -20.45 -30.93 20.0 -1 300.0 -20.56 -30.73 20.0 -1 300.0 -20.65 -30.54 20.0 -1 300.0 -20.73 -30.34 20.0 -1 300.0 -20.79 -30.15 20.0 -1 300.0 -20.84 -29.96 20.0 -1 300.0 -20.87 -29.78 20.0 -1 300.0 -20.88 -29.59 20.0 -1 300.0 -20.88 -29.41 20.0 -1 300.0 -20.85 -29.24 20.0 -1 300.0 -20.82 -29.06 20.0 -1 300.0 -20.76 -28.89 20.0 -1 300.0 -20.7 -28.72 20.0 -1 300.0 -20.61 -28.56 20.0 -1 300.0 -20.51 -28.4 20.0 -1 300.0 -20.39 -28.24 20.0 -1 300.0 -20.26 -28.08 20.0 -1 300.0 -20.12 -27.93 20.0 -1 300.0 -19.96 -27.78 20.0 -1 300.0 -19.78 -27.64 20.0 -1 300.0 -19.59 -27.5 20.0 -1 300.0 -19.39 -27.36 20.0 -1 300.0 -19.18 -27.23 20.0 -1 300.0 -18.95 -27.09 20.0 -1 300.0 -18.71 -26.97 20.0 -1 300.0 -18.46 -26.84 20.0 -1 300.0 -18.2 -26.73 20.0 -1 300.0 -17.92 -26.61 20.0 -1 300.0 -17.64 -26.5 20.0 -1 300.0 -17.35 -26.39 20.0 -1 300.0 -16.74 -26.18 20.0 -1 300.0 -16.42 -26.09 20.0 -1 300.0 -16.09 -25.99 20.0 -1 300.0 -15.76 -25.9 20.0 -1 300.0 -15.43 -25.82 20.0 -1 300.0 -15.08 -25.74 20.0 -1 300.0 -14.74 -25.66 20.0 -1 300.0 -14.03 -25.52 20.0 -1 300.0 -13.67 -25.45 20.0 -1 300.0 -13.31 -25.39 20.0 -1 300.0 -12.95 -25.33 20.0 -1 300.0 -12.59 -25.28 20.0 -1 300.0 -12.23 -25.23 20.0 -1 300.0 -11.87 -25.18 20.0 -1 300.0 -11.51 -25.14 20.0 -1 300.0 -11.15 -25.1 20.0 -1 300.0 -10.82 -25.07 20.0 -1 300.0 -10.5 -25.04 20.0 -1 300.0 -10.17 -25.02 20.0 -1 300.0 -9.85 -25.0 20.0 -1 300.0 -9.54 -24.98 20.0 -1 300.0 -9.23 -24.96 20.0 -1 300.0 -8.92 -24.95 20.0 -1 300.0 -8.63 -24.94 20.0 -1 300.0 -8.33 -24.94 20.0 -1 300.0 -8.05 -24.94 20.0 -1 300.0 -7.77 -24.94 20.0 -1 300.0 -7.5 -24.95 20.0 -1 300.0 -7.24 -24.95 20.0 -1 300.0 -6.99 -24.97 20.0 -1 300.0 -6.75 -24.98 20.0 -1 300.0 -6.52 -25.0 20.0 -1 300.0 -6.29 -25.02 20.0 -1 300.0 -6.08 -25.05 20.0 -1 300.0 -5.88 -25.07 20.0 -1 300.0 -5.69 -25.11 20.0 -1 300.0 -5.52 -25.14 20.0 -1 300.0 -5.35 -25.18 20.0 -1 300.0 -5.2 -25.22 20.0 -1 300.0 -5.06 -25.26 20.0 -1 300.0 -4.93 -25.31 20.0 -1 300.0 -4.81 -25.36 20.0 -1 300.0 -4.71 -25.41 20.0 -1 300.0 -4.62 -25.46 20.0 -1 300.0 -4.55 -25.52 20.0 -1 300.0 -4.49 -25.58 20.0 -1 300.0 -4.44 -25.64 20.0 -1 300.0 -4.41 -25.71 20.0 -1 300.0 -4.39 -25.77 20.0 -1 300.0 -4.38 -25.84 20.0 -1 300.0 -4.39 -25.92 20.0 -1 300.0 -4.42 -25.99 20.0 -1 300.0 -4.45 -26.07 20.0 -1 300.0 -4.51 -26.15 20.0 -1 300.0 -4.57 -26.23 20.0 -1 300.0 -4.65 -26.32 20.0 -1 300.0 -4.75 -26.41 20.0 -1 300.0 -4.86 -26.5 20.0 -1 300.0 -4.98 -26.59 20.0 -1 300.0 -5.12 -26.68 20.0 -1 300.0 -5.27 -26.78 20.0 -1 300.0 -5.43 -26.87 20.0 -1 300.0 -5.8 -27.07 20.0 -1 300.0 -6.0 -27.18 20.0 -1 300.0 -6.22 -27.28 20.0 -1 300.0 -6.68 -27.5 20.0 -1 300.0 -7.75 -27.94 20.0 -1 300.0 -8.05 -28.06 20.0 -1 300.0 -8.35 -28.17 20.0 -1 300.0 -8.99 -28.41 20.0 -1 300.0 -10.36 -28.89 20.0 -1 300.0 -10.75 -29.02 20.0 -1 300.0 -11.15 -29.16 20.0 -1 300.0 -11.97 -29.43 20.0 -1 300.0 -13.66 -29.97 20.0 -1 300.0 -17.11 -31.07 20.0 -1 300.0 -17.54 -31.2 20.0 -1 300.0 -17.96 -31.34 20.0 -1 300.0 -18.79 -31.6 20.0 -1 300.0 -20.37 -32.13 20.0 -1 300.0 -20.75 -32.26 20.0 -1 300.0 -21.11 -32.38 20.0 -1 300.0 -21.82 -32.63 20.0 -1 300.0 -23.09 -33.11 20.0 -1 300.0 -23.38 -33.23 20.0 -1 300.0 -23.66 -33.34 20.0 -1 300.0 -24.16 -33.56 20.0 -1 300.0 -24.4 -33.67 20.0 -1 300.0 -24.61 -33.77 20.0 -1 300.0 -25.0 -33.97 20.0 -1 300.0 -25.18 -34.07 20.0 -1 300.0 -25.33 -34.17 20.0 -1 300.0 -25.47 -34.26 20.0 -1 300.0 -25.59 -34.35 20.0 -1 300.0 -25.7 -34.44 20.0 -1 300.0 -25.79 -34.52 20.0 -1 300.0 -25.86 -34.6 20.0 -1 300.0 -25.92 -34.68 20.0 -1 300.0 -25.96 -34.75 20.0 -1 300.0 -25.98 -34.83 20.0 -1 300.0 -25.99 -34.9 20.0 -1 300.0 -25.98 -34.96 20.0 -1 300.0 -25.95 -35.02 20.0 -1 300.0 -25.9 -35.08 20.0 -1 300.0 -25.84 -35.14 20.0 -1 300.0 -25.76 -35.19 20.0 -1 300.0 -25.67 -35.24 20.0 -1 300.0 -25.56 -35.28 20.0 -1 300.0 -25.43 -35.33 20.0 -1 300.0 -25.29 -35.36 20.0 -1 300.0 -25.13 -35.4 20.0 -1 300.0 -24.96 -35.43 20.0 -1 300.0 -24.78 -35.45 20.0 -1 300.0 -24.58 -35.48 20.0 -1 300.0 -24.37 -35.5 20.0 -1 300.0 -24.14 -35.51 20.0 -1 300.0 -23.91 -35.52 20.0 -1 300.0 -23.66 -35.53 20.0 -1 300.0 -23.4 -35.53 20.0 -1 300.0 -23.13 -35.53 20.0 -1 300.0 -22.85 -35.53 20.0 -1 300.0 -22.56 -35.52 20.0 -1 300.0 -22.26 -35.51 20.0 -1 300.0 -21.95 -35.49 20.0 -1 300.0 -21.64 -35.47 20.0 -1 300.0 -21.31 -35.45 20.0 -1 300.0 -20.98 -35.42 20.0 -1 300.0 -20.64 -35.38 20.0 -1 300.0 -20.3 -35.35 20.0 -1 300.0 -19.95 -35.31 20.0 -1 300.0 -19.59 -35.26 20.0 -1 300.0 -19.24 -35.21 20.0 -1 300.0 -18.88 -35.16 20.0 -1 300.0 -18.51 -35.1 20.0 -1 300.0 -18.14 -35.04 20.0 -1 300.0 -17.78 -34.97 20.0 -1 300.0 -17.04 -34.83 20.0 -1 300.0 -16.67 -34.75 20.0 -1 300.0 -16.31 -34.67 20.0 -1 300.0 -15.58 -34.49 20.0 -1 300.0 -15.22 -34.4 20.0 -1 300.0 -14.87 -34.3 20.0 -1 300.0 -14.17 -34.09 20.0 -1 300.0 -13.83 -33.98 20.0 -1 300.0 -13.5 -33.86 20.0 -1 300.0 -13.18 -33.74 20.0 -1 300.0 -12.86 -33.62 20.0 -1 300.0 -12.55 -33.49 20.0 -1 300.0 -12.25 -33.36 20.0 -1 300.0 -11.68 -33.08 20.0 -1 300.0 -11.4 -32.94 20.0 -1 300.0 -11.14 -32.79 20.0 -1 300.0 -10.9 -32.64 20.0 -1 300.0 -10.66 -32.48 20.0 -1 300.0 -10.44 -32.33 20.0 -1 300.0 -10.22 -32.16 20.0 -1 300.0 -10.03 -32.0 20.0 -1 300.0 -9.84 -31.83 20.0 -1 300.0 -9.67 -31.65 20.0 -1 300.0 -9.51 -31.48 20.0 -1 300.0 -9.37 -31.3 20.0 -1 300.0 -9.24 -31.11 20.0 -1 300.0 -9.13 -30.92 20.0 -1 300.0 -9.03 -30.73 20.0 -1 300.0 -8.95 -30.54 20.0 -1 300.0 -8.88 -30.34 20.0 -1 300.0 -8.84 -30.14 20.0 -1 300.0 -8.8 -29.93 20.0 -1 300.0 -8.78 -29.73 20.0 -1 300.0 -8.78 -29.52 20.0 -1 300.0 -8.79 -29.3 20.0 -1 300.0 -8.82 -29.09 20.0 -1 300.0 -8.87 -28.87 20.0 -1 300.0 -8.93 -28.64 20.0 -1 300.0 -9.01 -28.43 20.0 -1 300.0 -9.09 -28.22 20.0 -1 300.0 -9.19 -28.01 20.0 -1 300.0 -9.31 -27.79 20.0 -1 300.0 -9.44 -27.57 20.0 -1 300.0 -9.58 -27.35 20.0 -1 300.0 -9.9 -26.9 20.0 -1 300.0 -10.08 -26.68 20.0 -1 300.0 -10.27 -26.45 20.0 -1 300.0 -10.69 -25.98 20.0 -1 300.0 -10.92 -25.75 20.0 -1 300.0 -11.16 -25.51 20.0 -1 300.0 -11.68 -25.03 20.0 -1 300.0 -11.95 -24.79 20.0 -1 300.0 -12.23 -24.55 20.0 -1 300.0 -12.82 -24.06 20.0 -1 300.0 -14.11 -23.07 20.0 -1 300.0 -17.0 -21.04 20.0 -1 300.0 -17.38 -20.78 20.0 -1 300.0 -17.76 -20.52 20.0 -1 300.0 -18.53 -20.01 20.0 -1 300.0 -20.08 -18.98 20.0 -1 300.0 -20.46 -18.72 20.0 -1 300.0 -20.84 -18.46 20.0 -1 300.0 -21.6 -17.95 20.0 -1 300.0 -23.07 -16.93 20.0 -1 300.0 -23.43 -16.67 20.0 -1 300.0 -23.78 -16.42 20.0 -1 300.0 -24.45 -15.91 20.0 -1 300.0 -25.72 -14.91 20.0 -1 300.0 -26.01 -14.66 20.0 -1 300.0 -26.3 -14.42 20.0 -1 300.0 -26.83 -13.93 20.0 -1 300.0 -27.09 -13.69 20.0 -1 300.0 -27.33 -13.45 20.0 -1 300.0 -27.78 -12.97 20.0 -1 300.0 -28.0 -12.71 20.0 -1 300.0 -28.21 -12.46 20.0 -1 300.0 -28.4 -12.21 20.0 -1 300.0 -28.58 -11.96 20.0 -1 300.0 -28.75 -11.71 20.0 -1 300.0 -28.89 -11.47 20.0 -1 300.0 -29.03 -11.23 20.0 -1 300.0 -29.14 -10.99 20.0 -1 300.0 -29.24 -10.75 20.0 -1 300.0 -29.32 -10.51 20.0 -1 300.0 -29.39 -10.28 20.0 -1 300.0 -29.44 -10.05 20.0 -1 300.0 -29.48 -9.82 20.0 -1 300.0 -29.49 -9.6 20.0 -1 300.0 -29.49 -9.38 20.0 -1 300.0 -29.48 -9.16 20.0 -1 300.0 -29.44 -8.95 20.0 -1 300.0 -29.39 -8.73 20.0 -1 300.0 -29.32 -8.53 20.0 -1 300.0 -29.24 -8.32 20.0 -1 300.0 -29.14 -8.12 20.0 -1 300.0 -29.03 -7.92 20.0 -1 300.0 -28.9 -7.72 20.0 -1 300.0 -28.75 -7.53 20.0 -1 300.0 -28.59 -7.34 20.0 -1 300.0 -28.42 -7.16 20.0 -1 300.0 -28.23 -6.97 20.0 -1 300.0 -28.02 -6.8 20.0 -1 300.0 -27.8 -6.62 20.0 -1 300.0 -27.57 -6.45 20.0 -1 300.0 -27.07 -6.12 20.0 -1 300.0 -26.8 -5.96 20.0 -1 300.0 -26.52 -5.8 20.0 -1 300.0 -25.93 -5.5 20.0 -1 300.0 -25.62 -5.36 20.0 -1 300.0 -25.3 -5.22 20.0 -1 300.0 -24.63 -4.95 20.0 -1 300.0 -24.28 -4.82 20.0 -1 300.0 -23.93 -4.69 20.0 -1 300.0 -23.21 -4.46 20.0 -1 300.0 -22.84 -4.34 20.0 -1 300.0 -22.46 -4.24 20.0 -1 300.0 -21.71 -4.03 20.0 -1 300.0 -21.32 -3.94 20.0 -1 300.0 -20.94 -3.84 20.0 -1 300.0 -20.17 -3.67 20.0 -1 300.0 -19.79 -3.59 20.0 -1 300.0 -19.4 -3.52 20.0 -1 300.0 -18.64 -3.38 20.0 -1 300.0 -18.27 -3.31 20.0 -1 300.0 -17.89 -3.25 20.0 -1 300.0 -17.53 -3.2 20.0 -1 300.0 -17.16 -3.15 20.0 -1 300.0 -16.81 -3.1 20.0 -1 300.0 -16.46 -3.06 20.0 -1 300.0 -16.12 -3.02 20.0 -1 300.0 -15.78 -2.98 20.0 -1 300.0 -15.48 -2.95 20.0 -1 300.0 -15.18 -2.92 20.0 -1 300.0 -14.89 -2.9 20.0 -1 300.0 -14.61 -2.88 20.0 -1 300.0 -14.34 -2.87 20.0 -1 300.0 -14.08 -2.85 20.0 -1 300.0 -13.83 -2.85 20.0 -1 300.0 -13.59 -2.84 20.0 -1 300.0 -13.36 -2.84 20.0 -1 300.0 -13.14 -2.84 20.0 -1 300.0 -12.93 -2.84 20.0 -1 300.0 -12.73 -2.85 20.0 -1 300.0 -12.55 -2.86 20.0 -1 300.0 -12.38 -2.87 20.0 -1 300.0 -12.22 -2.89 20.0 -1 300.0 -12.07 -2.91 20.0 -1 300.0 -11.94 -2.93 20.0 -1 300.0 -11.82 -2.96 20.0 -1 300.0 -11.72 -2.98 20.0 -1 300.0 -11.63 -3.01 20.0 -1 300.0 -11.55 -3.05 20.0 -1 300.0 -11.48 -3.08 20.0 -1 300.0 -11.44 -3.12 20.0 -1 300.0 -11.4 -3.17 20.0 -1 300.0 -11.38 -3.21 20.0 -1 300.0 -11.37 -3.26 20.0 -1 300.0 -11.38 -3.31 20.0 -1 300.0 -11.4 -3.36 20.0 -1 300.0 -11.44 -3.42 20.0 -1 300.0 -11.49 -3.47 20.0 -1 300.0 -11.56 -3.53 20.0 -1 300.0 -11.64 -3.59 20.0 -1 300.0 -11.73 -3.66 20.0 -1 300.0 -11.84 -3.72 20.0 -1 300.0 -11.96 -3.79 20.0 -1 300.0 -12.09 -3.86 20.0 -1 300.0 -12.24 -3.94 20.0 -1 300.0 -12.4 -4.01 20.0 -1 300.0 -12.77 -4.17 20.0 -1 300.0 -12.97 -4.25 20.0 -1 300.0 -13.18 -4.33 20.0 -1 300.0 -13.64 -4.5 20.0 -1 300.0 -14.69 -4.85 20.0 -1 300.0 -14.98 -4.94 20.0 -1 300.0 -15.28 -5.04 20.0 -1 300.0 -15.9 -5.22 20.0 -1 300.0 -17.23 -5.62 20.0 -1 300.0 -20.15 -6.43 20.0 -1 300.0 -20.52 -6.53 20.0 -1 300.0 -20.89 -6.63 20.0 -1 300.0 -21.63 -6.84 20.0 -1 300.0 -23.11 -7.24 20.0 -1 300.0 -25.89 -8.03 20.0 -1 300.0 -26.22 -8.12 20.0 -1 300.0 -26.54 -8.22 20.0 -1 300.0 -27.14 -8.4 20.0 -1 300.0 -28.26 -8.76 20.0 -1 300.0 -28.51 -8.85 20.0 -1 300.0 -28.76 -8.93 20.0 -1 300.0 -29.21 -9.1 20.0 -1 300.0 -29.43 -9.18 20.0 -1 300.0 -29.62 -9.25 20.0 -1 300.0 -29.99 -9.4 20.0 -1 300.0 -30.15 -9.48 20.0 -1 300.0 -30.3 -9.55 20.0 -1 300.0 -30.43 -9.62 20.0 -1 300.0 -30.56 -9.68 20.0 -1 300.0 -30.67 -9.75 20.0 -1 300.0 -30.77 -9.81 20.0 -1 300.0 -30.85 -9.87 20.0 -1 300.0 -30.92 -9.93 20.0 -1 300.0 -30.97 -9.99 20.0 -1 300.0 -31.02 -10.04 20.0 -1 300.0 -31.04 -10.09 20.0 -1 300.0 -31.06 -10.14 20.0 -1 300.0 -31.06 -10.19 20.0 -1 300.0 -31.04 -10.23 20.0 -1 300.0 -31.02 -10.27 20.0 -1 300.0 -30.97 -10.31 20.0 -1 300.0 -30.92 -10.35 20.0 -1 300.0 -30.85 -10.38 20.0 -1 300.0 -30.76 -10.41 20.0 -1 300.0 -30.67 -10.44 20.0 -1 300.0 -30.56 -10.47 20.0 -1 300.0 -30.43 -10.49 20.0 -1 300.0 -30.3 -10.51 20.0 -1 300.0 -30.15 -10.53 20.0 -1 300.0 -29.98 -10.54 20.0 -1 300.0 -29.81 -10.55 20.0 -1 300.0 -29.62 -10.56 20.0 -1 300.0 -29.42 -10.56 20.0 -1 300.0 -29.21 -10.56 20.0 -1 300.0 -28.99 -10.56 20.0 -1 300.0 -28.76 -10.56 20.0 -1 300.0 -28.52 -10.55 20.0 -1 300.0 -28.24 -10.54 20.0 -1 300.0 -27.95 -10.52 20.0 -1 300.0 -27.66 -10.5 20.0 -1 300.0 -27.35 -10.48 20.0 -1 300.0 -27.03 -10.45 20.0 -1 300.0 -26.7 -10.42 20.0 -1 300.0 -26.37 -10.38 20.0 -1 300.0 -26.02 -10.34 20.0 -1 300.0 -25.67 -10.3 20.0 -1 300.0 -25.31 -10.25 20.0 -1 300.0 -24.57 -10.15 20.0 -1 300.0 -24.19 -10.09 20.0 -1 300.0 -23.81 -10.02 20.0 -1 300.0 -23.03 -9.88 20.0 -1 300.0 -22.64 -9.81 20.0 -1 300.0 -22.25 -9.73 20.0 -1 300.0 -21.45 -9.56 20.0 -1 300.0 -21.06 -9.46 20.0 -1 300.0 -20.66 -9.37 20.0 -1 300.0 -19.88 -9.16 20.0 -1 300.0 -19.49 -9.05 20.0 -1 300.0 -19.1 -8.94 20.0 -1 300.0 -18.34 -8.7 20.0 -1 300.0 -17.97 -8.58 20.0 -1 300.0 -17.61 -8.45 20.0 -1 300.0 -16.9 -8.18 20.0 -1 300.0 -16.55 -8.04 20.0 -1 300.0 -16.22 -7.89 20.0 -1 300.0 -15.57 -7.59 20.0 -1 300.0 -15.27 -7.44 20.0 -1 300.0 -14.97 -7.28 20.0 -1 300.0 -14.41 -6.95 20.0 -1 300.0 -14.15 -6.77 20.0 -1 300.0 -13.9 -6.6 20.0 -1 300.0 -13.67 -6.42 20.0 -1 300.0 -13.45 -6.24 20.0 -1 300.0 -13.24 -6.05 20.0 -1 300.0 -13.04 -5.86 20.0 -1 300.0 -12.86 -5.67 20.0 -1 300.0 -12.7 -5.47 20.0 -1 300.0 -12.55 -5.27 20.0 -1 300.0 -12.41 -5.07 20.0 -1 300.0 -12.29 -4.86 20.0 -1 300.0 -12.19 -4.65 20.0 -1 300.0 -12.1 -4.44 20.0 -1 300.0 -12.03 -4.22 20.0 -1 300.0 -11.97 -4.0 20.0 -1 300.0 -11.94 -3.78 20.0 -1 300.0 -11.91 -3.56 20.0 -1 300.0 -11.9 -3.33 20.0 -1 300.0 -11.91 -3.1 20.0 -1 300.0 -11.94 -2.86 20.0 -1 300.0 -11.98 -2.63 20.0 -1 300.0 -12.04 -2.39 20.0 -1 300.0 -12.11 -2.14 20.0 -1 300.0 -12.2 -1.9 20.0 -1 300.0 -12.3 -1.67 20.0 -1 300.0 -12.41 -1.44 20.0 -1 300.0 -12.54 -1.2 20.0 -1 300.0 -12.68 -0.96 20.0 -1 300.0 -12.83 -0.73 20.0 -1 300.0 -12.99 -0.49 20.0 -1 300.0 -13.36 0.0 20.0 -1 300.0 -13.55 0.25 20.0 -1 300.0 -13.77 0.49 20.0 -1 300.0 -14.23 0.99 20.0 -1 300.0 -15.27 2.01 20.0 -1 300.0 -15.55 2.27 20.0 -1 300.0 -15.84 2.52 20.0 -1 300.0 -16.45 3.04 20.0 -1 300.0 -17.75 4.09 20.0 -1 300.0 -20.57 6.22 20.0 -1 300.0 -20.93 6.49 20.0 -1 300.0 -21.3 6.75 20.0 -1 300.0 -22.02 7.29 20.0 -1 300.0 -23.46 8.35 20.0 -1 300.0 -23.81 8.62 20.0 -1 300.0 -24.15 8.88 20.0 -1 300.0 -24.84 9.41 20.0 -1 300.0 -26.13 10.46 20.0 -1 300.0 -26.43 10.72 20.0 -1 300.0 -26.73 10.97 20.0 -1 300.0 -27.3 11.49 20.0 -1 300.0 -27.57 11.74 20.0 -1 300.0 -27.83 12.0 20.0 -1 300.0 -28.32 12.5 20.0 -1 300.0 -28.55 12.75 20.0 -1 300.0 -28.77 13.0 20.0 -1 300.0 -28.98 13.24 20.0 -1 300.0 -29.17 13.49 20.0 -1 300.0 -29.36 13.73 20.0 -1 300.0 -29.53 13.97 20.0 -1 300.0 -29.69 14.21 20.0 -1 300.0 -29.83 14.45 20.0 -1 300.0 -29.97 14.7 20.0 -1 300.0 -30.1 14.95 20.0 -1 300.0 -30.21 15.2 20.0 -1 300.0 -30.31 15.45 20.0 -1 300.0 -30.39 15.69 20.0 -1 300.0 -30.45 15.94 20.0 -1 300.0 -30.49 16.18 20.0 -1 300.0 -30.52 16.41 20.0 -1 300.0 -30.53 16.64 20.0 -1 300.0 -30.53 16.87 20.0 -1 300.0 -30.5 17.1 20.0 -1 300.0 -30.47 17.33 20.0 -1 300.0 -30.41 17.55 20.0 -1 300.0 -30.34 17.77 20.0 -1 300.0 -30.25 17.98 20.0 -1 300.0 -30.14 18.19 20.0 -1 300.0 -30.02 18.4 20.0 -1 300.0 -29.88 18.6 20.0 -1 300.0 -29.73 18.8 20.0 -1 300.0 -29.56 19.0 20.0 -1 300.0 -29.38 19.2 20.0 -1 300.0 -29.18 19.39 20.0 -1 300.0 -28.96 19.57 20.0 -1 300.0 -28.73 19.76 20.0 -1 300.0 -28.49 19.93 20.0 -1 300.0 -28.23 20.11 20.0 -1 300.0 -27.96 20.28 20.0 -1 300.0 -27.68 20.45 20.0 -1 300.0 -27.39 20.61 20.0 -1 300.0 -27.08 20.77 20.0 -1 300.0 -26.43 21.08 20.0 -1 300.0 -26.1 21.23 20.0 -1 300.0 -25.75 21.37 20.0 -1 300.0 -25.02 21.65 20.0 -1 300.0 -24.65 21.78 20.0 -1 300.0 -24.27 21.91 20.0 -1 300.0 -23.49 22.15 20.0 -1 300.0 -23.09 22.26 20.0 -1 300.0 -22.69 22.38 20.0 -1 300.0 -21.88 22.58 20.0 -1 300.0 -21.47 22.68 20.0 -1 300.0 -21.05 22.77 20.0 -1 300.0 -20.22 22.95 20.0 -1 300.0 -19.81 23.03 20.0 -1 300.0 -19.4 23.11 20.0 -1 300.0 -18.57 23.25 20.0 -1 300.0 -18.17 23.31 20.0 -1 300.0 -17.77 23.37 20.0 -1 300.0 -16.98 23.48 20.0 -1 300.0 -16.59 23.52 20.0 -1 300.0 -16.21 23.57 20.0 -1 300.0 -15.84 23.61 20.0 -1 300.0 -15.47 23.64 20.0 -1 300.0 -15.12 23.67 20.0 -1 300.0 -14.77 23.7 20.0 -1 300.0 -14.43 23.72 20.0 -1 300.0 -14.1 23.74 20.0 -1 300.0 -13.79 23.75 20.0 -1 300.0 -13.49 23.76 20.0 -1 300.0 -13.2 23.77 20.0 -1 300.0 -12.92 23.77 20.0 -1 300.0 -12.66 23.77 20.0 -1 300.0 -12.4 23.77 20.0 -1 300.0 -12.16 23.76 20.0 -1 300.0 -11.94 23.75 20.0 -1 300.0 -11.72 23.73 20.0 -1 300.0 -11.53 23.71 20.0 -1 300.0 -11.34 23.69 20.0 -1 300.0 -11.17 23.66 20.0 -1 300.0 -11.02 23.63 20.0 -1 300.0 -10.88 23.6 20.0 -1 300.0 -10.75 23.56 20.0 -1 300.0 -10.64 23.52 20.0 -1 300.0 -10.55 23.48 20.0 -1 300.0 -10.47 23.43 20.0 -1 300.0 -10.41 23.39 20.0 -1 300.0 -10.37 23.33 20.0 -1 300.0 -10.34 23.28 20.0 -1 300.0 -10.32 23.22 20.0 -1 300.0 -10.33 23.16 20.0 -1 300.0 -10.34 23.1 20.0 -1 300.0 -10.38 23.03 20.0 -1 300.0 -10.43 22.96 20.0 -1 300.0 -10.5 22.89 20.0 -1 300.0 -10.58 22.82 20.0 -1 300.0 -10.68 22.74 20.0 -1 300.0 -10.79 22.66 20.0 -1 300.0 -10.92 22.58 20.0 -1 300.0 -11.06 22.49 20.0 -1 300.0 -11.22 22.41 20.0 -1 300.0 -11.39 22.32 20.0 -1 300.0 -11.77 22.14 20.0 -1 300.0 -11.98 22.04 20.0 -1 300.0 -12.21 21.95 20.0 -1 300.0 -12.7 21.75 20.0 -1 300.0 -12.96 21.64 20.0 -1 300.0 -13.23 21.54 20.0 -1 300.0 -13.81 21.33 20.0 -1 300.0 -15.07 20.89 20.0 -1 300.0 -15.4 20.78 20.0 -1 300.0 -15.74 20.67 20.0 -1 300.0 -16.44 20.44 20.0 -1 300.0 -17.9 19.98 20.0 -1 300.0 -20.87 19.04 20.0 -1 300.0 -21.21 18.93 20.0 -1 300.0 -21.55 18.82 20.0 -1 300.0 -22.21 18.6 20.0 -1 300.0 -23.47 18.17 20.0 -1 300.0 -23.77 18.07 20.0 -1 300.0 -24.07 17.96 20.0 -1 300.0 -24.63 17.76 20.0 -1 300.0 -25.65 17.36 20.0 -1 300.0 -25.88 17.27 20.0 -1 300.0 -26.1 17.17 20.0 -1 300.0 -26.51 16.98 20.0 -1 300.0 -26.7 16.89 20.0 -1 300.0 -26.87 16.8 20.0 -1 300.0 -27.18 16.63 20.0 -1 300.0 -27.32 16.55 20.0 -1 300.0 -27.45 16.46 20.0 -1 300.0 -27.56 16.39 20.0 -1 300.0 -27.66 16.31 20.0 -1 300.0 -27.74 16.23 20.0 -1 300.0 -27.82 16.16 20.0 -1 300.0 -27.87 16.08 20.0 -1 300.0 -27.92 16.01 20.0 -1 300.0 -27.95 15.95 20.0 -1 300.0 -27.96 15.88 20.0 -1 300.0 -27.96 15.82 20.0 -1 300.0 -27.95 15.76 20.0 -1 300.0 -27.93 15.7 20.0 -1 300.0 -27.89 15.64 20.0 -1 300.0 -27.83 15.59 20.0 -1 300.0 -27.76 15.54 20.0 -1 300.0 -27.68 15.49 20.0 -1 300.0 -27.59 15.44 20.0 -1 300.0 -27.48 15.4 20.0 -1 300.0 -27.35 15.36 20.0 -1 300.0 -27.21 15.32 20.0 -1 300.0 -27.06 15.29 20.0 -1 300.0 -26.9 15.25 20.0 -1 300.0 -26.72 15.22 20.0 -1 300.0 -26.53 15.2 20.0 -1 300.0 -26.33 15.17 20.0 -1 300.0 -26.12 15.15 20.0 -1 300.0 -25.89 15.14 20.0 -1 300.0 -25.65 15.12 20.0 -1 300.0 -25.41 15.11 20.0 -1 300.0 -25.14 15.1 20.0 -1 300.0 -24.88 15.1 20.0 -1 300.0 -24.59 15.1 20.0 -1 300.0 -24.3 15.1 20.0 -1 300.0 -24.0 15.1 20.0 -1 300.0 -23.69 15.11 20.0 -1 300.0 -23.38 15.12 20.0 -1 300.0 -23.05 15.13 20.0 -1 300.0 -22.72 15.15 20.0 -1 300.0 -22.38 15.17 20.0 -1 300.0 -22.0 15.2 20.0 -1 300.0 -21.61 15.23 20.0 -1 300.0 -21.22 15.26 20.0 -1 300.0 -20.82 15.3 20.0 -1 300.0 -20.42 15.34 20.0 -1 300.0 -20.01 15.38 20.0 -1 300.0 -19.18 15.49 20.0 -1 300.0 -18.76 15.55 20.0 -1 300.0 -18.34 15.61 20.0 -1 300.0 -17.49 15.74 20.0 -1 300.0 -17.07 15.82 20.0 -1 300.0 -16.64 15.9 20.0 -1 300.0 -15.8 16.06 20.0 -1 300.0 -15.38 16.15 20.0 -1 300.0 -14.97 16.25 20.0 -1 300.0 -14.15 16.45 20.0 -1 300.0 -13.75 16.55 20.0 -1 300.0 -13.35 16.66 20.0 -1 300.0 -12.58 16.89 20.0 -1 300.0 -12.21 17.02 20.0 -1 300.0 -11.84 17.14 20.0 -1 300.0 -11.14 17.41 20.0 -1 300.0 -10.8 17.54 20.0 -1 300.0 -10.48 17.68 20.0 -1 300.0 -9.86 17.98 20.0 -1 300.0 -9.57 18.13 20.0 -1 300.0 -9.29 18.28 20.0 -1 300.0 -9.02 18.44 20.0 -1 300.0 -8.77 18.6 20.0 -1 300.0 -8.53 18.77 20.0 -1 300.0 -8.3 18.94 20.0 -1 300.0 -8.09 19.11 20.0 -1 300.0 -7.9 19.29 20.0 -1 300.0 -7.72 19.47 20.0 -1 300.0 -7.55 19.65 20.0 -1 300.0 -7.4 19.84 20.0 -1 300.0 -7.27 20.03 20.0 -1 300.0 -7.15 20.22 20.0 -1 300.0 -7.05 20.42 20.0 -1 300.0 -6.96 20.62 20.0 -1 300.0 -6.89 20.82 20.0 -1 300.0 -6.84 21.02 20.0 -1 300.0 -6.81 21.23 20.0 -1 300.0 -6.79 21.44 20.0 -1 300.0 -6.78 21.65 20.0 -1 300.0 -6.8 21.87 20.0 -1 300.0 -6.83 22.09 20.0 -1 300.0 -6.87 22.31 20.0 -1 300.0 -6.93 22.53 20.0 -1 300.0 -7.01 22.76 20.0 -1 300.0 -7.1 22.99 20.0 -1 300.0 -7.21 23.22 20.0 -1 300.0 -7.34 23.45 20.0 -1 300.0 -7.48 23.68 20.0 -1 300.0 -7.63 23.92 20.0 -1 300.0 -7.98 24.4 20.0 -1 300.0 -8.16 24.63 20.0 -1 300.0 -8.36 24.86 20.0 -1 300.0 -8.78 25.32 20.0 -1 300.0 -9.75 26.25 20.0 -1 300.0 -10.02 26.49 20.0 -1 300.0 -10.29 26.73 20.0 -1 300.0 -10.86 27.2 20.0 -1 300.0 -12.09 28.17 20.0 -1 300.0 -12.41 28.41 20.0 -1 300.0 -12.73 28.66 20.0 -1 300.0 -13.39 29.14 20.0 -1 300.0 -14.75 30.12 20.0 -1 300.0 -17.46 32.08 20.0 -1 300.0 -17.79 32.32 20.0 -1 300.0 -18.11 32.56 20.0 -1 300.0 -18.74 33.04 20.0 -1 300.0 -19.93 33.99 20.0 -1 300.0 -20.21 34.23 20.0 -1 300.0 -20.48 34.46 20.0 -1 300.0 -21.0 34.93 20.0 -1 300.0 -21.24 35.16 20.0 -1 300.0 -21.47 35.39 20.0 -1 300.0 -21.91 35.84 20.0 -1 300.0 -22.11 36.06 20.0 -1 300.0 -22.3 36.28 20.0 -1 300.0 -22.48 36.51 20.0 -1 300.0 -22.65 36.72 20.0 -1 300.0 -22.8 36.94 20.0 -1 300.0 -22.94 37.16 20.0 -1 300.0 -23.07 37.37 20.0 -1 300.0 -23.18 37.58 20.0 -1 300.0 -23.29 37.79 20.0 -1 300.0 -23.37 37.99 20.0 -1 300.0 -23.45 38.2 20.0 -1 300.0 -23.51 38.4 20.0 -1 300.0 -23.55 38.6 20.0 -1 300.0 -23.59 38.8 20.0 -1 300.0 -23.6 38.99 20.0 -1 300.0 -23.61 39.18 20.0 -1 300.0 -23.59 39.39 20.0 -1 300.0 -23.56 39.59 20.0 -1 300.0 -23.52 39.79 20.0 -1 300.0 -23.45 39.98 20.0 -1 300.0 -23.37 40.17 20.0 -1 300.0 -23.27 40.36 20.0 -1 300.0 -23.16 40.55 20.0 -1 300.0 -23.03 40.73 20.0 -1 300.0 -22.88 40.91 20.0 -1 300.0 -22.72 41.09 20.0 -1 300.0 -22.54 41.26 20.0 -1 300.0 -22.34 41.42 20.0 -1 300.0 -22.13 41.59 20.0 -1 300.0 -21.91 41.75 20.0 -1 300.0 -21.67 41.91 20.0 -1 300.0 -21.41 42.06 20.0 -1 300.0 -21.14 42.21 20.0 -1 300.0 -20.86 42.35 20.0 -1 300.0 -20.57 42.49 20.0 -1 300.0 -20.26 42.63 20.0 -1 300.0 -19.94 42.76 20.0 -1 300.0 -19.6 42.89 20.0 -1 300.0 -18.91 43.14 20.0 -1 300.0 -18.54 43.25 20.0 -1 300.0 -18.17 43.37 20.0 -1 300.0 -17.79 43.47 20.0 -1 300.0 -17.39 43.58 20.0 -1 300.0 -17.0 43.68 20.0 -1 300.0 -16.59 43.77 20.0 -1 300.0 -15.76 43.95 20.0 -1 300.0 -15.34 44.03 20.0 -1 300.0 -14.91 44.11 20.0 -1 300.0 -14.48 44.18 20.0 -1 300.0 -14.04 44.25 20.0 -1 300.0 -13.61 44.32 20.0 -1 300.0 -13.17 44.38 20.0 -1 300.0 -12.29 44.49 20.0 -1 300.0 -11.85 44.53 20.0 -1 300.0 -11.41 44.58 20.0 -1 300.0 -10.98 44.62 20.0 -1 300.0 -10.55 44.65 20.0 -1 300.0 -10.12 44.68 20.0 -1 300.0 -9.69 44.7 20.0 -1 300.0 -9.27 44.73 20.0 -1 300.0 -8.86 44.74 20.0 -1 300.0 -8.45 44.76 20.0 -1 300.0 -8.04 44.76 20.0 -1 300.0 -7.65 44.77 20.0 -1 300.0 -7.26 44.77 20.0 -1 300.0 -6.88 44.76 20.0 -1 300.0 -6.52 44.75 20.0 -1 300.0 -6.16 44.74 20.0 -1 300.0 -5.81 44.72 20.0 -1 300.0 -5.47 44.7 20.0 -1 300.0 -5.14 44.68 20.0 -1 300.0 -4.83 44.65 20.0 -1 300.0 -4.53 44.61 20.0 -1 300.0 -4.24 44.58 20.0 -1 300.0 -3.96 44.53 20.0 -1 300.0 -3.7 44.49 20.0 -1 300.0 -3.46 44.44 20.0 -1 300.0 -3.23 44.39 20.0 -1 300.0 -3.01 44.33 20.0 -1 300.0 -2.81 44.27 20.0 -1 300.0 -2.63 44.21 20.0 -1 300.0 -2.46 44.14 20.0 -1 300.0 -2.31 44.07 20.0 -1 300.0 -2.17 44.0 20.0 -1 300.0 -2.04 43.92 20.0 -1 300.0 -1.94 43.84 20.0 -1 300.0 -1.85 43.76 20.0 -1 300.0 -1.77 43.67 20.0 -1 300.0 -1.72 43.59 20.0 -1 300.0 -1.67 43.49 20.0 -1 300.0 -1.65 43.4 20.0 -1 300.0 -1.64 43.3 20.0 -1 300.0 -1.65 43.2 20.0 -1 300.0 -1.67 43.09 20.0 -1 300.0 -1.71 42.99 20.0 -1 300.0 -1.76 42.88 20.0 -1 300.0 -1.83 42.77 20.0 -1 300.0 -1.92 42.65 20.0 -1 300.0 -2.02 42.53 20.0 -1 300.0 -2.13 42.41 20.0 -1 300.0 -2.27 42.29 20.0 -1 300.0 -2.41 42.17 20.0 -1 300.0 -2.57 42.04 20.0 -1 300.0 -2.93 41.78 20.0 -1 300.0 -3.13 41.65 20.0 -1 300.0 -3.35 41.51 20.0 -1 300.0 -3.81 41.23 20.0 -1 300.0 -4.06 41.09 20.0 -1 300.0 -4.32 40.95 20.0 -1 300.0 -4.87 40.66 20.0 -1 300.0 -6.08 40.07 20.0 -1 300.0 -8.79 38.84 20.0 -1 300.0 -9.14 38.68 20.0 -1 300.0 -9.49 38.53 20.0 -1 300.0 -10.21 38.21 20.0 -1 300.0 -11.61 37.58 20.0 -1 300.0 -14.21 36.34 20.0 -1 300.0 -14.49 36.2 20.0 -1 300.0 -14.76 36.06 20.0 -1 300.0 -15.26 35.78 20.0 -1 300.0 -15.5 35.65 20.0 -1 300.0 -15.73 35.51 20.0 -1 300.0 -16.16 35.24 20.0 -1 300.0 -16.36 35.11 20.0 -1 300.0 -16.55 34.98 20.0 -1 300.0 -16.73 34.84 20.0 -1 300.0 -16.89 34.72 20.0 -1 300.0 -17.05 34.59 20.0 -1 300.0 -17.19 34.47 20.0 -1 300.0 -17.32 34.34 20.0 -1 300.0 -17.43 34.22 20.0 -1 300.0 -17.54 34.1 20.0 -1 300.0 -17.63 33.98 20.0 -1 300.0 -17.7 33.87 20.0 -1 300.0 -17.76 33.75 20.0 -1 300.0 -17.81 33.64 20.0 -1 300.0 -17.85 33.53 20.0 -1 300.0 -17.87 33.42 20.0 -1 300.0 -17.88 33.31 20.0 -1 300.0 -17.87 33.21 20.0 -1 300.0 -17.84 33.11 20.0 -1 300.0 -17.81 33.01 20.0 -1 300.0 -17.76 32.91 20.0 -1 300.0 -17.7 32.82 20.0 -1 300.0 -17.62 32.73 20.0 -1 300.0 -17.52 32.64 20.0 -1 300.0 -17.42 32.55 20.0 -1 300.0 -17.3 32.47 20.0 -1 300.0 -17.16 32.39 20.0 -1 300.0 -17.01 32.31 20.0 -1 300.0 -16.85 32.23 20.0 -1 300.0 -16.68 32.16 20.0 -1 300.0 -16.49 32.09 20.0 -1 300.0 -16.29 32.02 20.0 -1 300.0 -16.07 31.96 20.0 -1 300.0 -15.85 31.89 20.0 -1 300.0 -15.61 31.84 20.0 -1 300.0 -15.36 31.78 20.0 -1 300.0 -15.1 31.73 20.0 -1 300.0 -14.83 31.68 20.0 -1 300.0 -14.54 31.63 20.0 -1 300.0 -14.25 31.59 20.0 -1 300.0 -13.95 31.55 20.0 -1 300.0 -13.63 31.51 20.0 -1 300.0 -13.31 31.48 20.0 -1 300.0 -12.98 31.44 20.0 -1 300.0 -12.64 31.42 20.0 -1 300.0 -12.29 31.39 20.0 -1 300.0 -11.93 31.37 20.0 -1 300.0 -11.57 31.35 20.0 -1 300.0 -11.2 31.34 20.0 -1 300.0 -10.82 31.33 20.0 -1 300.0 -10.44 31.32 20.0 -1 300.0 -10.06 31.31 20.0 -1 300.0 -9.67 31.31 20.0 -1 300.0 -9.27 31.32 20.0 -1 300.0 -8.87 31.32 20.0 -1 300.0 -8.47 31.33 20.0 -1 300.0 -8.07 31.34 20.0 -1 300.0 -7.63 31.36 20.0 -1 300.0 -7.19 31.38 20.0 -1 300.0 -6.75 31.4 20.0 -1 300.0 -6.3 31.43 20.0 -1 300.0 -5.86 31.47 20.0 -1 300.0 -5.42 31.5 20.0 -1 300.0 -4.98 31.54 20.0 -1 300.0 -4.55 31.59 20.0 -1 300.0 -4.11 31.64 20.0 -1 300.0 -3.68 31.69 20.0 -1 300.0 -3.26 31.75 20.0 -1 300.0 -2.84 31.81 20.0 -1 300.0 -2.43 31.87 20.0 -1 300.0 -2.02 31.94 20.0 -1 300.0 -1.23 32.09 20.0 -1 300.0 -0.85 32.17 20.0 -1 300.0 -0.47 32.26 20.0 -1 300.0 -0.11 32.34 20.0 -1 300.0 0.24 32.43 20.0 -1 300.0 0.59 32.53 20.0 -1 300.0 0.92 32.63 20.0 -1 300.0 1.55 32.84 20.0 -1 300.0 1.84 32.95 20.0 -1 300.0 2.12 33.06 20.0 -1 300.0 2.39 33.18 20.0 -1 300.0 2.65 33.3 20.0 -1 300.0 2.89 33.42 20.0 -1 300.0 3.11 33.55 20.0 -1 300.0 3.32 33.68 20.0 -1 300.0 3.52 33.81 20.0 -1 300.0 3.7 33.95 20.0 -1 300.0 3.86 34.09 20.0 -1 300.0 4.01 34.24 20.0 -1 300.0 4.14 34.38 20.0 -1 300.0 4.26 34.53 20.0 -1 300.0 4.36 34.69 20.0 -1 300.0 4.44 34.84 20.0 -1 300.0 4.5 35.0 20.0 -1 300.0 4.55 35.16 20.0 -1 300.0 4.59 35.33 20.0 -1 300.0 4.6 35.49 20.0 -1 300.0 4.6 35.66 20.0 -1 300.0 4.58 35.83 20.0 -1 300.0 4.55 36.01 20.0 -1 300.0 4.5 36.19 20.0 -1 300.0 4.43 36.36 20.0 -1 300.0 4.35 36.55 20.0 -1 300.0 4.25 36.73 20.0 -1 300.0 4.14 36.92 20.0 -1 300.0 4.01 37.1 20.0 -1 300.0 3.87 37.29 20.0 -1 300.0 3.71 37.49 20.0 -1 300.0 3.36 37.88 20.0 -1 300.0 3.16 38.07 20.0 -1 300.0 2.94 38.27 20.0 -1 300.0 2.48 38.67 20.0 -1 300.0 1.43 39.5 20.0 -1 300.0 1.16 39.69 20.0 -1 300.0 0.88 39.88 20.0 -1 300.0 0.3 40.28 20.0 -1 300.0 -0.93 41.07 20.0 -1 300.0 -3.54 42.67 20.0 -1 300.0 -3.87 42.87 20.0 -1 300.0 -4.2 43.07 20.0 -1 300.0 -4.86 43.46 20.0 -1 300.0 -6.14 44.25 20.0 -1 300.0 -6.44 44.45 20.0 -1 300.0 -6.75 44.64 20.0 -1 300.0 -7.34 45.03 20.0 -1 300.0 -8.43 45.79 20.0 -1 300.0 -8.68 45.98 20.0 -1 300.0 -8.93 46.16 20.0 -1 300.0 -9.38 46.53 20.0 -1 300.0 -9.6 46.71 20.0 -1 300.0 -9.8 46.89 20.0 -1 300.0 -10.17 47.24 20.0 -1 300.0 -10.34 47.41 20.0 -1 300.0 -10.49 47.59 20.0 -1 300.0 -10.64 47.76 20.0 -1 300.0 -10.77 47.92 20.0 -1 300.0 -10.88 48.09 20.0 -1 300.0 -10.99 48.26 20.0 -1 300.0 -11.08 48.42 20.0 -1 300.0 -11.15 48.58 20.0 -1 300.0 -11.22 48.73 20.0 -1 300.0 -11.27 48.89 20.0 -1 300.0 -11.3 49.04 20.0 -1 300.0 -11.32 49.19 20.0 -1 300.0 -11.33 49.34 20.0 -1 300.0 -11.32 49.48 20.0 -1 300.0 -11.3 49.62 20.0 -1 300.0 -11.26 49.76 20.0 -1 300.0 -11.21 49.9 20.0 -1 300.0 -11.14 50.03 20.0 -1 300.0 -11.06 50.16 20.0 -1 300.0 -10.96 50.29 20.0 -1 300.0 -10.85 50.42 20.0 -1 300.0 -10.73 50.54 20.0 -1 300.0 -10.59 50.66 20.0 -1 300.0 -10.44 50.77 20.0 -1 300.0 -10.28 50.89 20.0 -1 300.0 -10.1 50.99 20.0 -1 300.0 -9.91 51.1 20.0 -1 300.0 -9.71 51.2 20.0 -1 300.0 -9.5 51.3 20.0 -1 300.0 -9.27 51.39 20.0 -1 300.0 -8.78 51.57 20.0 -1 300.0 -8.52 51.66 20.0 -1 300.0 -8.25 51.74 20.0 -1 300.0 -7.97 51.82 20.0 -1 300.0 -7.67 51.9 20.0 -1 300.0 -7.37 51.97 20.0 -1 300.0 -7.06 52.04 20.0 -1 300.0 -6.41 52.16 20.0 -1 300.0 -6.07 52.22 20.0 -1 300.0 -5.72 52.28 20.0 -1 300.0 -5.37 52.33 20.0 -1 300.0 -5.01 52.38 20.0 -1 300.0 -4.64 52.42 20.0 -1 300.0 -4.26 52.46 20.0 -1 300.0 -3.89 52.5 20.0 -1 300.0 -3.5 52.53 20.0 -1 300.0 -3.11 52.56 20.0 -1 300.0 -2.72 52.59 20.0 -1 300.0 -2.32 52.61 20.0 -1 300.0 -1.92 52.63 20.0 -1 300.0 -1.52 52.65 20.0 -1 300.0 -1.12 52.66 20.0 -1 300.0 -0.71 52.67 20.0 -1 300.0 -0.3 52.67 20.0 -1 300.0 0.1 52.67 20.0 -1 300.0 0.51 52.67 20.0 -1 300.0 0.92 52.66 20.0 -1 300.0 1.32 52.65 20.0 -1 300.0 1.72 52.64 20.0 -1 300.0 2.13 52.62 20.0 -1 300.0 2.52 52.6 20.0 -1 300.0 2.92 52.58 20.0 -1 300.0 3.31 52.55 20.0 -1 300.0 3.7 52.52 20.0 -1 300.0 4.08 52.48 20.0 -1 300.0 4.46 52.44 20.0 -1 300.0 4.83 52.4 20.0 -1 300.0 5.19 52.35 20.0 -1 300.0 5.55 52.3 20.0 -1 300.0 5.9 52.25 20.0 -1 300.0 6.24 52.19 20.0 -1 300.0 6.58 52.13 20.0 -1 300.0 6.9 52.07 20.0 -1 300.0 7.22 52.0 20.0 -1 300.0 7.53 51.93 20.0 -1 300.0 7.82 51.86 20.0 -1 300.0 8.39 51.7 20.0 -1 300.0 8.66 51.62 20.0 -1 300.0 8.91 51.53 20.0 -1 300.0 9.15 51.44 20.0 -1 300.0 9.39 51.35 20.0 -1 300.0 9.61 51.25 20.0 -1 300.0 9.81 51.15 20.0 -1 300.0 10.01 51.05 20.0 -1 300.0 10.19 50.94 20.0 -1 300.0 10.37 50.82 20.0 -1 300.0 10.54 50.7 20.0 -1 300.0 10.69 50.57 20.0 -1 300.0 10.83 50.44 20.0 -1 300.0 10.95 50.31 20.0 -1 300.0 11.05 50.17 20.0 -1 300.0 11.14 50.04 20.0 -1 300.0 11.21 49.89 20.0 -1 300.0 11.26 49.75 20.0 -1 300.0 11.3 49.6 20.0 -1 300.0 11.32 49.45 20.0 -1 300.0 11.33 49.29 20.0 -1 300.0 11.32 49.14 20.0 -1 300.0 11.29 48.98 20.0 -1 300.0 11.24 48.81 20.0 -1 300.0 11.19 48.65 20.0 -1 300.0 11.11 48.48 20.0 -1 300.0 11.02 48.31 20.0 -1 300.0 10.91 48.13 20.0 -1 300.0 10.79 47.96 20.0 -1 300.0 10.65 47.78 20.0 -1 300.0 10.5 47.6 20.0 -1 300.0 10.16 47.23 20.0 -1 300.0 9.97 47.04 20.0 -1 300.0 9.76 46.85 20.0 -1 300.0 9.31 46.47 20.0 -1 300.0 8.28 45.68 20.0 -1 300.0 8.0 45.48 20.0 -1 300.0 7.71 45.28 20.0 -1 300.0 7.1 44.87 20.0 -1 300.0 5.8 44.04 20.0 -1 300.0 3.01 42.35 20.0 -1 300.0 2.66 42.14 20.0 -1 300.0 2.31 41.92 20.0 -1 300.0 1.62 41.5 20.0 -1 300.0 0.27 40.65 20.0 -1 300.0 -0.05 40.44 20.0 -1 300.0 -0.36 40.23 20.0 -1 300.0 -0.97 39.82 20.0 -1 300.0 -2.09 38.99 20.0 -1 300.0 -2.32 38.8 20.0 -1 300.0 -2.55 38.62 20.0 -1 300.0 -2.97 38.24 20.0 -1 300.0 -3.17 38.06 20.0 -1 300.0 -3.35 37.88 20.0 -1 300.0 -3.69 37.52 20.0 -1 300.0 -3.84 37.34 20.0 -1 300.0 -3.97 37.16 20.0 -1 300.0 -4.1 36.99 20.0 -1 300.0 -4.21 36.81 20.0 -1 300.0 -4.3 36.64 20.0 -1 300.0 -4.39 36.47 20.0 -1 300.0 -4.46 36.3 20.0 -1 300.0 -4.51 36.14 20.0 -1 300.0 -4.56 35.98 20.0 -1 300.0 -4.59 35.81 20.0 -1 300.0 -4.6 35.66 20.0 -1 300.0 -4.6 35.5 20.0 -1 300.0 -4.59 35.34 20.0 -1 300.0 -4.56 35.19 20.0 -1 300.0 -4.52 35.04 20.0 -1 300.0 -4.46 34.89 20.0 -1 300.0 -4.39 34.75 20.0 -1 300.0 -4.31 34.6 20.0 -1 300.0 -4.21 34.47 20.0 -1 300.0 -4.09 34.33 20.0 -1 300.0 -3.97 34.19 20.0 -1 300.0 -3.83 34.06 20.0 -1 300.0 -3.67 33.93 20.0 -1 300.0 -3.5 33.8 20.0 -1 300.0 -3.32 33.68 20.0 -1 300.0 -3.13 33.56 20.0 -1 300.0 -2.92 33.44 20.0 -1 300.0 -2.7 33.32 20.0 -1 300.0 -2.47 33.21 20.0 -1 300.0 -2.22 33.1 20.0 -1 300.0 -1.7 32.89 20.0 -1 300.0 -1.42 32.79 20.0 -1 300.0 -1.13 32.7 20.0 -1 300.0 -0.83 32.6 20.0 -1 300.0 -0.52 32.51 20.0 -1 300.0 -0.2 32.42 20.0 -1 300.0 0.13 32.34 20.0 -1 300.0 0.81 32.18 20.0 -1 300.0 1.17 32.1 20.0 -1 300.0 1.53 32.03 20.0 -1 300.0 1.9 31.96 20.0 -1 300.0 2.27 31.9 20.0 -1 300.0 2.65 31.84 20.0 -1 300.0 3.04 31.78 20.0 -1 300.0 3.82 31.67 20.0 -1 300.0 4.22 31.63 20.0 -1 300.0 4.62 31.58 20.0 -1 300.0 5.03 31.54 20.0 -1 300.0 5.43 31.5 20.0 -1 300.0 5.84 31.47 20.0 -1 300.0 6.25 31.44 20.0 -1 300.0 6.66 31.41 20.0 -1 300.0 7.07 31.39 20.0 -1 300.0 7.51 31.36 20.0 -1 300.0 7.96 31.34 20.0 -1 300.0 8.4 31.33 20.0 -1 300.0 8.84 31.32 20.0 -1 300.0 9.27 31.32 20.0 -1 300.0 9.7 31.31 20.0 -1 300.0 10.12 31.32 20.0 -1 300.0 10.54 31.32 20.0 -1 300.0 10.96 31.33 20.0 -1 300.0 11.36 31.34 20.0 -1 300.0 11.76 31.36 20.0 -1 300.0 12.15 31.38 20.0 -1 300.0 12.53 31.41 20.0 -1 300.0 12.91 31.44 20.0 -1 300.0 13.27 31.47 20.0 -1 300.0 13.62 31.51 20.0 -1 300.0 13.96 31.55 20.0 -1 300.0 14.29 31.59 20.0 -1 300.0 14.61 31.64 20.0 -1 300.0 14.92 31.69 20.0 -1 300.0 15.21 31.75 20.0 -1 300.0 15.49 31.81 20.0 -1 300.0 15.75 31.87 20.0 -1 300.0 16.0 31.94 20.0 -1 300.0 16.24 32.01 20.0 -1 300.0 16.46 32.08 20.0 -1 300.0 16.67 32.16 20.0 -1 300.0 16.86 32.23 20.0 -1 300.0 17.03 32.32 20.0 -1 300.0 17.19 32.4 20.0 -1 300.0 17.33 32.49 20.0 -1 300.0 17.46 32.59 20.0 -1 300.0 17.57 32.68 20.0 -1 300.0 17.66 32.78 20.0 -1 300.0 17.74 32.88 20.0 -1 300.0 17.8 32.99 20.0 -1 300.0 17.84 33.09 20.0 -1 300.0 17.87 33.2 20.0 -1 300.0 17.88 33.32 20.0 -1 300.0 17.87 33.43 20.0 -1 300.0 17.84 33.55 20.0 -1 300.0 17.8 33.67 20.0 -1 300.0 17.74 33.79 20.0 -1 300.0 17.67 33.92 20.0 -1 300.0 17.58 34.05 20.0 -1 300.0 17.47 34.17 20.0 -1 300.0 17.35 34.31 20.0 -1 300.0 17.21 34.44 20.0 -1 300.0 17.06 34.58 20.0 -1 300.0 16.9 34.72 20.0 -1 300.0 16.52 35.0 20.0 -1 300.0 16.31 35.14 20.0 -1 300.0 16.09 35.28 20.0 -1 300.0 15.61 35.58 20.0 -1 300.0 15.36 35.73 20.0 -1 300.0 15.09 35.88 20.0 -1 300.0 14.52 36.18 20.0 -1 300.0 13.28 36.81 20.0 -1 300.0 12.96 36.96 20.0 -1 300.0 12.63 37.12 20.0 -1 300.0 11.95 37.43 20.0 -1 300.0 10.56 38.05 20.0 -1 300.0 7.75 39.3 20.0 -1 300.0 7.4 39.46 20.0 -1 300.0 7.07 39.61 20.0 -1 300.0 6.41 39.91 20.0 -1 300.0 5.17 40.51 20.0 -1 300.0 4.88 40.66 20.0 -1 300.0 4.6 40.8 20.0 -1 300.0 4.07 41.09 20.0 -1 300.0 3.83 41.23 20.0 -1 300.0 3.59 41.37 20.0 -1 300.0 3.15 41.64 20.0 -1 300.0 2.95 41.77 20.0 -1 300.0 2.76 41.9 20.0 -1 300.0 2.58 42.03 20.0 -1 300.0 2.42 42.16 20.0 -1 300.0 2.28 42.28 20.0 -1 300.0 2.15 42.4 20.0 -1 300.0 2.03 42.52 20.0 -1 300.0 1.93 42.64 20.0 -1 300.0 1.84 42.75 20.0 -1 300.0 1.77 42.87 20.0 -1 300.0 1.71 42.98 20.0 -1 300.0 1.67 43.08 20.0 -1 300.0 1.65 43.19 20.0 -1 300.0 1.64 43.29 20.0 -1 300.0 1.65 43.39 20.0 -1 300.0 1.67 43.48 20.0 -1 300.0 1.71 43.58 20.0 -1 300.0 1.76 43.66 20.0 -1 300.0 1.84 43.75 20.0 -1 300.0 1.93 43.84 20.0 -1 300.0 2.03 43.91 20.0 -1 300.0 2.15 43.99 20.0 -1 300.0 2.29 44.06 20.0 -1 300.0 2.44 44.13 20.0 -1 300.0 2.6 44.2 20.0 -1 300.0 2.79 44.27 20.0 -1 300.0 2.98 44.32 20.0 -1 300.0 3.19 44.38 20.0 -1 300.0 3.42 44.43 20.0 -1 300.0 3.66 44.48 20.0 -1 300.0 3.92 44.53 20.0 -1 300.0 4.18 44.57 20.0 -1 300.0 4.44 44.6 20.0 -1 300.0 4.71 44.63 20.0 -1 300.0 5.0 44.66 20.0 -1 300.0 5.29 44.69 20.0 -1 300.0 5.59 44.71 20.0 -1 300.0 5.9 44.73 20.0 -1 300.0 6.22 44.74 20.0 -1 300.0 6.55 44.75 20.0 -1 300.0 6.89 44.76 20.0 -1 300.0 7.24 44.77 20.0 -1 300.0 7.59 44.77 20.0 -1 300.0 7.95 44.76 20.0 -1 300.0 8.31 44.76 20.0 -1 300.0 8.68 44.75 20.0 -1 300.0 9.06 44.73 20.0 -1 300.0 9.44 44.72 20.0 -1 300.0 9.83 44.7 20.0 -1 300.0 10.22 44.67 20.0 -1 300.0 10.61 44.64 20.0 -1 300.0 11.0 44.61 20.0 -1 300.0 11.4 44.58 20.0 -1 300.0 11.8 44.54 20.0 -1 300.0 12.6 44.45 20.0 -1 300.0 13.0 44.4 20.0 -1 300.0 13.4 44.35 20.0 -1 300.0 13.8 44.29 20.0 -1 300.0 14.2 44.23 20.0 -1 300.0 14.6 44.16 20.0 -1 300.0 14.99 44.1 20.0 -1 300.0 15.77 43.95 20.0 -1 300.0 16.15 43.87 20.0 -1 300.0 16.52 43.79 20.0 -1 300.0 17.26 43.61 20.0 -1 300.0 17.62 43.52 20.0 -1 300.0 17.98 43.42 20.0 -1 300.0 18.66 43.22 20.0 -1 300.0 18.99 43.11 20.0 -1 300.0 19.31 43.0 20.0 -1 300.0 19.63 42.88 20.0 -1 300.0 19.93 42.77 20.0 -1 300.0 20.22 42.65 20.0 -1 300.0 20.51 42.52 20.0 -1 300.0 21.04 42.26 20.0 -1 300.0 21.29 42.13 20.0 -1 300.0 21.53 41.99 20.0 -1 300.0 21.76 41.85 20.0 -1 300.0 21.97 41.7 20.0 -1 300.0 22.18 41.56 20.0 -1 300.0 22.37 41.41 20.0 -1 300.0 22.54 41.25 20.0 -1 300.0 22.71 41.1 20.0 -1 300.0 22.86 40.94 20.0 -1 300.0 23.0 40.77 20.0 -1 300.0 23.12 40.61 20.0 -1 300.0 23.23 40.44 20.0 -1 300.0 23.32 40.27 20.0 -1 300.0 23.41 40.09 20.0 -1 300.0 23.48 39.92 20.0 -1 300.0 23.53 39.74 20.0 -1 300.0 23.57 39.54 20.0 -1 300.0 23.6 39.34 20.0 -1 300.0 23.61 39.14 20.0 -1 300.0 23.6 38.93 20.0 -1 300.0 23.57 38.72 20.0 -1 300.0 23.53 38.51 20.0 -1 300.0 23.48 38.29 20.0 -1 300.0 23.4 38.08 20.0 -1 300.0 23.32 37.85 20.0 -1 300.0 23.21 37.63 20.0 -1 300.0 23.09 37.41 20.0 -1 300.0 22.95 37.18 20.0 -1 300.0 22.8 36.95 20.0 -1 300.0 22.64 36.72 20.0 -1 300.0 22.27 36.24 20.0 -1 300.0 22.06 36.01 20.0 -1 300.0 21.84 35.77 20.0 -1 300.0 21.36 35.28 20.0 -1 300.0 20.27 34.28 20.0 -1 300.0 19.98 34.03 20.0 -1 300.0 19.67 33.78 20.0 -1 300.0 19.03 33.27 20.0 -1 300.0 17.67 32.23 20.0 -1 300.0 17.32 31.97 20.0 -1 300.0 16.96 31.71 20.0 -1 300.0 16.24 31.19 20.0 -1 300.0 14.77 30.14 20.0 -1 300.0 14.4 29.88 20.0 -1 300.0 14.04 29.61 20.0 -1 300.0 13.32 29.09 20.0 -1 300.0 11.92 28.04 20.0 -1 300.0 11.59 27.78 20.0 -1 300.0 11.26 27.52 20.0 -1 300.0 10.63 27.01 20.0 -1 300.0 10.32 26.75 20.0 -1 300.0 10.03 26.5 20.0 -1 300.0 9.47 25.99 20.0 -1 300.0 9.2 25.74 20.0 -1 300.0 8.95 25.49 20.0 -1 300.0 8.48 24.99 20.0 -1 300.0 8.27 24.75 20.0 -1 300.0 8.06 24.5 20.0 -1 300.0 7.7 24.02 20.0 -1 300.0 7.55 23.8 20.0 -1 300.0 7.41 23.58 20.0 -1 300.0 7.29 23.36 20.0 -1 300.0 7.18 23.14 20.0 -1 300.0 7.08 22.93 20.0 -1 300.0 7.0 22.71 20.0 -1 300.0 6.92 22.5 20.0 -1 300.0 6.87 22.3 20.0 -1 300.0 6.83 22.09 20.0 -1 300.0 6.8 21.88 20.0 -1 300.0 6.78 21.68 20.0 -1 300.0 6.79 21.48 20.0 -1 300.0 6.8 21.29 20.0 -1 300.0 6.83 21.09 20.0 -1 300.0 6.87 20.9 20.0 -1 300.0 6.93 20.71 20.0 -1 300.0 7.0 20.52 20.0 -1 300.0 7.09 20.34 20.0 -1 300.0 7.19 20.15 20.0 -1 300.0 7.31 19.98 20.0 -1 300.0 7.43 19.8 20.0 -1 300.0 7.58 19.63 20.0 -1 300.0 7.73 19.45 20.0 -1 300.0 7.9 19.29 20.0 -1 300.0 8.09 19.12 20.0 -1 300.0 8.28 18.96 20.0 -1 300.0 8.49 18.8 20.0 -1 300.0 8.71 18.64 20.0 -1 300.0 8.94 18.49 20.0 -1 300.0 9.19 18.34 20.0 -1 300.0 9.71 18.05 20.0 -1 300.0 9.99 17.91 20.0 -1 300.0 10.28 17.77 20.0 -1 300.0 10.88 17.51 20.0 -1 300.0 11.2 17.38 20.0 -1 300.0 11.53 17.26 20.0 -1 300.0 12.2 17.02 20.0 -1 300.0 12.55 16.91 20.0 -1 300.0 12.91 16.8 20.0 -1 300.0 13.64 16.58 20.0 -1 300.0 14.01 16.48 20.0 -1 300.0 14.39 16.39 20.0 -1 300.0 15.16 16.2 20.0 -1 300.0 15.55 16.12 20.0 -1 300.0 15.94 16.04 20.0 -1 300.0 16.73 15.88 20.0 -1 300.0 17.13 15.81 20.0 -1 300.0 17.52 15.74 20.0 -1 300.0 18.32 15.61 20.0 -1 300.0 18.71 15.55 20.0 -1 300.0 19.1 15.5 20.0 -1 300.0 19.49 15.45 20.0 -1 300.0 19.88 15.4 20.0 -1 300.0 20.26 15.36 20.0 -1 300.0 20.64 15.32 20.0 -1 300.0 21.02 15.28 20.0 -1 300.0 21.39 15.24 20.0 -1 300.0 21.74 15.21 20.0 -1 300.0 22.09 15.19 20.0 -1 300.0 22.44 15.17 20.0 -1 300.0 22.78 15.15 20.0 -1 300.0 23.11 15.13 20.0 -1 300.0 23.43 15.12 20.0 -1 300.0 23.75 15.11 20.0 -1 300.0 24.05 15.1 20.0 -1 300.0 24.35 15.1 20.0 -1 300.0 24.64 15.1 20.0 -1 300.0 24.91 15.1 20.0 -1 300.0 25.18 15.1 20.0 -1 300.0 25.44 15.11 20.0 -1 300.0 25.68 15.12 20.0 -1 300.0 25.92 15.14 20.0 -1 300.0 26.14 15.16 20.0 -1 300.0 26.35 15.18 20.0 -1 300.0 26.55 15.2 20.0 -1 300.0 26.74 15.23 20.0 -1 300.0 26.91 15.26 20.0 -1 300.0 27.08 15.29 20.0 -1 300.0 27.23 15.32 20.0 -1 300.0 27.36 15.36 20.0 -1 300.0 27.48 15.4 20.0 -1 300.0 27.59 15.45 20.0 -1 300.0 27.69 15.49 20.0 -1 300.0 27.77 15.54 20.0 -1 300.0 27.84 15.59 20.0 -1 300.0 27.89 15.64 20.0 -1 300.0 27.93 15.7 20.0 -1 300.0 27.95 15.76 20.0 -1 300.0 27.96 15.82 20.0 -1 300.0 27.96 15.88 20.0 -1 300.0 27.95 15.95 20.0 -1 300.0 27.92 16.01 20.0 -1 300.0 27.87 16.08 20.0 -1 300.0 27.82 16.16 20.0 -1 300.0 27.74 16.23 20.0 -1 300.0 27.66 16.3 20.0 -1 300.0 27.56 16.38 20.0 -1 300.0 27.45 16.46 20.0 -1 300.0 27.33 16.54 20.0 -1 300.0 27.04 16.71 20.0 -1 300.0 26.88 16.8 20.0 -1 300.0 26.71 16.89 20.0 -1 300.0 26.33 17.07 20.0 -1 300.0 26.12 17.16 20.0 -1 300.0 25.9 17.26 20.0 -1 300.0 25.43 17.45 20.0 -1 300.0 24.39 17.85 20.0 -1 300.0 21.93 18.69 20.0 -1 300.0 21.57 18.81 20.0 -1 300.0 21.21 18.93 20.0 -1 300.0 20.47 19.16 20.0 -1 300.0 18.98 19.64 20.0 -1 300.0 16.04 20.57 20.0 -1 300.0 15.69 20.69 20.0 -1 300.0 15.35 20.8 20.0 -1 300.0 14.68 21.02 20.0 -1 300.0 13.46 21.46 20.0 -1 300.0 13.18 21.56 20.0 -1 300.0 12.9 21.67 20.0 -1 300.0 12.4 21.87 20.0 -1 300.0 12.16 21.97 20.0 -1 300.0 11.94 22.06 20.0 -1 300.0 11.53 22.25 20.0 -1 300.0 11.35 22.34 20.0 -1 300.0 11.18 22.43 20.0 -1 300.0 11.02 22.52 20.0 -1 300.0 10.88 22.6 20.0 -1 300.0 10.76 22.68 20.0 -1 300.0 10.65 22.76 20.0 -1 300.0 10.55 22.84 20.0 -1 300.0 10.48 22.91 20.0 -1 300.0 10.41 22.98 20.0 -1 300.0 10.37 23.05 20.0 -1 300.0 10.34 23.12 20.0 -1 300.0 10.32 23.18 20.0 -1 300.0 10.32 23.24 20.0 -1 300.0 10.34 23.3 20.0 -1 300.0 10.38 23.35 20.0 -1 300.0 10.43 23.4 20.0 -1 300.0 10.5 23.45 20.0 -1 300.0 10.58 23.5 20.0 -1 300.0 10.68 23.54 20.0 -1 300.0 10.79 23.58 20.0 -1 300.0 10.93 23.61 20.0 -1 300.0 11.07 23.64 20.0 -1 300.0 11.23 23.67 20.0 -1 300.0 11.41 23.7 20.0 -1 300.0 11.6 23.72 20.0 -1 300.0 11.81 23.74 20.0 -1 300.0 12.03 23.75 20.0 -1 300.0 12.26 23.76 20.0 -1 300.0 12.51 23.77 20.0 -1 300.0 12.77 23.77 20.0 -1 300.0 13.04 23.77 20.0 -1 300.0 13.32 23.77 20.0 -1 300.0 13.6 23.76 20.0 -1 300.0 13.89 23.75 20.0 -1 300.0 14.18 23.73 20.0 -1 300.0 14.49 23.72 20.0 -1 300.0 14.8 23.7 20.0 -1 300.0 15.12 23.67 20.0 -1 300.0 15.45 23.64 20.0 -1 300.0 15.78 23.61 20.0 -1 300.0 16.13 23.58 20.0 -1 300.0 16.48 23.54 20.0 -1 300.0 16.83 23.5 20.0 -1 300.0 17.19 23.45 20.0 -1 300.0 17.55 23.4 20.0 -1 300.0 17.92 23.35 20.0 -1 300.0 18.67 23.23 20.0 -1 300.0 19.05 23.17 20.0 -1 300.0 19.42 23.1 20.0 -1 300.0 20.19 22.96 20.0 -1 300.0 20.57 22.88 20.0 -1 300.0 20.95 22.8 20.0 -1 300.0 21.71 22.62 20.0 -1 300.0 22.09 22.53 20.0 -1 300.0 22.47 22.43 20.0 -1 300.0 23.21 22.23 20.0 -1 300.0 23.57 22.13 20.0 -1 300.0 23.93 22.02 20.0 -1 300.0 24.64 21.78 20.0 -1 300.0 24.98 21.66 20.0 -1 300.0 25.32 21.54 20.0 -1 300.0 25.98 21.28 20.0 -1 300.0 26.29 21.14 20.0 -1 300.0 26.6 21.01 20.0 -1 300.0 27.19 20.72 20.0 -1 300.0 27.46 20.57 20.0 -1 300.0 27.73 20.42 20.0 -1 300.0 27.99 20.26 20.0 -1 300.0 28.24 20.11 20.0 -1 300.0 28.48 19.94 20.0 -1 300.0 28.7 19.78 20.0 -1 300.0 29.12 19.44 20.0 -1 300.0 29.3 19.27 20.0 -1 300.0 29.48 19.09 20.0 -1 300.0 29.64 18.91 20.0 -1 300.0 29.79 18.72 20.0 -1 300.0 29.93 18.54 20.0 -1 300.0 30.05 18.35 20.0 -1 300.0 30.16 18.16 20.0 -1 300.0 30.26 17.96 20.0 -1 300.0 30.34 17.76 20.0 -1 300.0 30.41 17.56 20.0 -1 300.0 30.46 17.36 20.0 -1 300.0 30.5 17.15 20.0 -1 300.0 30.52 16.94 20.0 -1 300.0 30.53 16.73 20.0 -1 300.0 30.53 16.52 20.0 -1 300.0 30.51 16.3 20.0 -1 300.0 30.47 16.07 20.0 -1 300.0 30.42 15.83 20.0 -1 300.0 30.35 15.58 20.0 -1 300.0 30.27 15.34 20.0 -1 300.0 30.16 15.09 20.0 -1 300.0 30.05 14.84 20.0 -1 300.0 29.91 14.59 20.0 -1 300.0 29.76 14.33 20.0 -1 300.0 29.6 14.07 20.0 -1 300.0 29.42 13.81 20.0 -1 300.0 29.01 13.29 20.0 -1 300.0 28.79 13.02 20.0 -1 300.0 28.55 12.75 20.0 -1 300.0 28.04 12.21 20.0 -1 300.0 27.77 11.94 20.0 -1 300.0 27.48 11.66 20.0 -1 300.0 26.88 11.11 20.0 -1 300.0 25.55 9.98 20.0 -1 300.0 22.57 7.69 20.0 -1 300.0 22.18 7.41 20.0 -1 300.0 21.79 7.12 20.0 -1 300.0 21.0 6.54 20.0 -1 300.0 19.44 5.38 20.0 -1 300.0 19.06 5.09 20.0 -1 300.0 18.68 4.81 20.0 -1 300.0 17.93 4.23 20.0 -1 300.0 16.51 3.1 20.0 -1 300.0 16.18 2.81 20.0 -1 300.0 15.85 2.53 20.0 -1 300.0 15.23 1.97 20.0 -1 300.0 14.93 1.7 20.0 -1 300.0 14.65 1.42 20.0 -1 300.0 14.12 0.88 20.0 -1 300.0 13.87 0.61 20.0 -1 300.0 13.63 0.34 20.0 -1 300.0 13.41 0.07 20.0 -1 300.0 13.2 -0.19 20.0 -1 300.0 13.01 -0.46 20.0 -1 300.0 12.83 -0.72 20.0 -1 300.0 12.67 -0.98 20.0 -1 300.0 12.52 -1.23 20.0 -1 300.0 12.39 -1.47 20.0 -1 300.0 12.28 -1.7 20.0 -1 300.0 12.19 -1.94 20.0 -1 300.0 12.11 -2.17 20.0 -1 300.0 12.04 -2.4 20.0 -1 300.0 11.98 -2.62 20.0 -1 300.0 11.94 -2.84 20.0 -1 300.0 11.92 -3.06 20.0 -1 300.0 11.9 -3.28 20.0 -1 300.0 11.91 -3.5 20.0 -1 300.0 11.93 -3.71 20.0 -1 300.0 11.96 -3.92 20.0 -1 300.0 12.01 -4.13 20.0 -1 300.0 12.07 -4.34 20.0 -1 300.0 12.14 -4.54 20.0 -1 300.0 12.23 -4.74 20.0 -1 300.0 12.34 -4.94 20.0 -1 300.0 12.45 -5.13 20.0 -1 300.0 12.58 -5.32 20.0 -1 300.0 12.73 -5.51 20.0 -1 300.0 12.89 -5.7 20.0 -1 300.0 13.06 -5.88 20.0 -1 300.0 13.24 -6.05 20.0 -1 300.0 13.44 -6.23 20.0 -1 300.0 13.65 -6.4 20.0 -1 300.0 13.87 -6.57 20.0 -1 300.0 14.1 -6.74 20.0 -1 300.0 14.35 -6.9 20.0 -1 300.0 14.6 -7.06 20.0 -1 300.0 14.86 -7.22 20.0 -1 300.0 15.42 -7.52 20.0 -1 300.0 15.72 -7.66 20.0 -1 300.0 16.02 -7.81 20.0 -1 300.0 16.65 -8.08 20.0 -1 300.0 16.98 -8.21 20.0 -1 300.0 17.31 -8.34 20.0 -1 300.0 17.99 -8.59 20.0 -1 300.0 18.34 -8.7 20.0 -1 300.0 18.7 -8.82 20.0 -1 300.0 19.42 -9.04 20.0 -1 300.0 20.9 -9.43 20.0 -1 300.0 21.28 -9.52 20.0 -1 300.0 21.65 -9.6 20.0 -1 300.0 22.4 -9.76 20.0 -1 300.0 22.77 -9.83 20.0 -1 300.0 23.14 -9.9 20.0 -1 300.0 23.87 -10.03 20.0 -1 300.0 24.23 -10.09 20.0 -1 300.0 24.58 -10.15 20.0 -1 300.0 24.94 -10.2 20.0 -1 300.0 25.28 -10.25 20.0 -1 300.0 25.62 -10.29 20.0 -1 300.0 25.96 -10.34 20.0 -1 300.0 26.6 -10.41 20.0 -1 300.0 26.91 -10.44 20.0 -1 300.0 27.21 -10.46 20.0 -1 300.0 27.5 -10.49 20.0 -1 300.0 27.78 -10.51 20.0 -1 300.0 28.05 -10.53 20.0 -1 300.0 28.31 -10.54 20.0 -1 300.0 28.57 -10.55 20.0 -1 300.0 28.81 -10.56 20.0 -1 300.0 29.04 -10.56 20.0 -1 300.0 29.26 -10.56 20.0 -1 300.0 29.47 -10.56 20.0 -1 300.0 29.66 -10.56 20.0 -1 300.0 29.85 -10.55 20.0 -1 300.0 30.02 -10.54 20.0 -1 300.0 30.18 -10.52 20.0 -1 300.0 30.33 -10.5 20.0 -1 300.0 30.46 -10.48 20.0 -1 300.0 30.58 -10.46 20.0 -1 300.0 30.69 -10.44 20.0 -1 300.0 30.78 -10.41 20.0 -1 300.0 30.86 -10.37 20.0 -1 300.0 30.93 -10.34 20.0 -1 300.0 30.98 -10.3 20.0 -1 300.0 31.02 -10.26 20.0 -1 300.0 31.05 -10.22 20.0 -1 300.0 31.06 -10.18 20.0 -1 300.0 31.05 -10.13 20.0 -1 300.0 31.04 -10.08 20.0 -1 300.0 31.01 -10.03 20.0 -1 300.0 30.96 -9.97 20.0 -1 300.0 30.9 -9.91 20.0 -1 300.0 30.83 -9.86 20.0 -1 300.0 30.74 -9.79 20.0 -1 300.0 30.64 -9.73 20.0 -1 300.0 30.52 -9.66 20.0 -1 300.0 30.4 -9.6 20.0 -1 300.0 30.25 -9.53 20.0 -1 300.0 30.1 -9.46 20.0 -1 300.0 29.75 -9.31 20.0 -1 300.0 29.56 -9.23 20.0 -1 300.0 29.36 -9.15 20.0 -1 300.0 28.92 -8.99 20.0 -1 300.0 27.9 -8.64 20.0 -1 300.0 27.62 -8.55 20.0 -1 300.0 27.34 -8.46 20.0 -1 300.0 26.73 -8.28 20.0 -1 300.0 25.44 -7.9 20.0 -1 300.0 22.59 -7.1 20.0 -1 300.0 22.19 -6.99 20.0 -1 300.0 21.79 -6.88 20.0 -1 300.0 20.98 -6.66 20.0 -1 300.0 19.37 -6.22 20.0 -1 300.0 18.98 -6.11 20.0 -1 300.0 18.58 -6.0 20.0 -1 300.0 17.81 -5.78 20.0 -1 300.0 16.35 -5.36 20.0 -1 300.0 16.0 -5.26 20.0 -1 300.0 15.66 -5.16 20.0 -1 300.0 15.02 -4.95 20.0 -1 300.0 14.71 -4.86 20.0 -1 300.0 14.41 -4.76 20.0 -1 300.0 13.85 -4.57 20.0 -1 300.0 13.59 -4.48 20.0 -1 300.0 13.34 -4.39 20.0 -1 300.0 12.88 -4.21 20.0 -1 300.0 12.68 -4.13 20.0 -1 300.0 12.48 -4.04 20.0 -1 300.0 12.14 -3.89 20.0 -1 300.0 11.99 -3.81 20.0 -1 300.0 11.86 -3.74 20.0 -1 300.0 11.74 -3.67 20.0 -1 300.0 11.64 -3.6 20.0 -1 300.0 11.55 -3.53 20.0 -1 300.0 11.49 -3.47 20.0 -1 300.0 11.43 -3.41 20.0 -1 300.0 11.4 -3.35 20.0 -1 300.0 11.38 -3.29 20.0 -1 300.0 11.37 -3.24 20.0 -1 300.0 11.39 -3.19 20.0 -1 300.0 11.41 -3.15 20.0 -1 300.0 11.46 -3.1 20.0 -1 300.0 11.52 -3.06 20.0 -1 300.0 11.6 -3.02 20.0 -1 300.0 11.69 -2.99 20.0 -1 300.0 11.8 -2.96 20.0 -1 300.0 11.93 -2.93 20.0 -1 300.0 12.07 -2.91 20.0 -1 300.0 12.22 -2.89 20.0 -1 300.0 12.39 -2.87 20.0 -1 300.0 12.58 -2.86 20.0 -1 300.0 12.78 -2.85 20.0 -1 300.0 12.99 -2.84 20.0 -1 300.0 13.21 -2.84 20.0 -1 300.0 13.45 -2.84 20.0 -1 300.0 13.7 -2.84 20.0 -1 300.0 13.97 -2.85 20.0 -1 300.0 14.24 -2.86 20.0 -1 300.0 14.53 -2.88 20.0 -1 300.0 14.82 -2.9 20.0 -1 300.0 15.13 -2.92 20.0 -1 300.0 15.43 -2.95 20.0 -1 300.0 15.73 -2.98 20.0 -1 300.0 16.04 -3.01 20.0 -1 300.0 16.35 -3.04 20.0 -1 300.0 16.68 -3.08 20.0 -1 300.0 17.0 -3.12 20.0 -1 300.0 17.68 -3.22 20.0 -1 300.0 18.02 -3.27 20.0 -1 300.0 18.37 -3.33 20.0 -1 300.0 19.07 -3.45 20.0 -1 300.0 19.43 -3.52 20.0 -1 300.0 19.78 -3.59 20.0 -1 300.0 20.5 -3.74 20.0 -1 300.0 20.86 -3.82 20.0 -1 300.0 21.21 -3.91 20.0 -1 300.0 21.93 -4.09 20.0 -1 300.0 22.28 -4.18 20.0 -1 300.0 22.63 -4.28 20.0 -1 300.0 23.31 -4.49 20.0 -1 300.0 23.65 -4.6 20.0 -1 300.0 23.98 -4.71 20.0 -1 300.0 24.63 -4.95 20.0 -1 300.0 24.95 -5.07 20.0 -1 300.0 25.25 -5.2 20.0 -1 300.0 25.85 -5.46 20.0 -1 300.0 26.13 -5.6 20.0 -1 300.0 26.4 -5.74 20.0 -1 300.0 26.67 -5.88 20.0 -1 300.0 26.93 -6.03 20.0 -1 300.0 27.17 -6.18 20.0 -1 300.0 27.41 -6.33 20.0 -1 300.0 27.84 -6.65 20.0 -1 300.0 28.04 -6.81 20.0 -1 300.0 28.23 -6.98 20.0 -1 300.0 28.41 -7.15 20.0 -1 300.0 28.57 -7.32 20.0 -1 300.0 28.73 -7.5 20.0 -1 300.0 28.86 -7.67 20.0 -1 300.0 28.99 -7.86 20.0 -1 300.0 29.1 -8.04 20.0 -1 300.0 29.2 -8.23 20.0 -1 300.0 29.28 -8.42 20.0 -1 300.0 29.35 -8.61 20.0 -1 300.0 29.41 -8.8 20.0 -1 300.0 29.45 -9.0 20.0 -1 300.0 29.48 -9.2 20.0 -1 300.0 29.49 -9.41 20.0 -1 300.0 29.49 -9.61 20.0 -1 300.0 29.48 -9.82 20.0 -1 300.0 29.45 -10.03 20.0 -1 300.0 29.4 -10.24 20.0 -1 300.0 29.34 -10.46 20.0 -1 300.0 29.27 -10.68 20.0 -1 300.0 29.18 -10.9 20.0 -1 300.0 29.08 -11.12 20.0 -1 300.0 28.96 -11.34 20.0 -1 300.0 28.82 -11.59 20.0 -1 300.0 28.67 -11.84 20.0 -1 300.0 28.49 -12.09 20.0 -1 300.0 28.3 -12.34 20.0 -1 300.0 28.1 -12.59 20.0 -1 300.0 27.88 -12.85 20.0 -1 300.0 27.4 -13.37 20.0 -1 300.0 27.14 -13.63 20.0 -1 300.0 26.87 -13.9 20.0 -1 300.0 26.28 -14.43 20.0 -1 300.0 24.97 -15.51 20.0 -1 300.0 24.61 -15.79 20.0 -1 300.0 24.25 -16.06 20.0 -1 300.0 23.5 -16.62 20.0 -1 300.0 21.92 -17.73 20.0 -1 300.0 18.57 -19.98 20.0 -1 300.0 18.15 -20.27 20.0 -1 300.0 17.73 -20.55 20.0 -1 300.0 16.9 -21.11 20.0 -1 300.0 15.29 -22.22 20.0 -1 300.0 14.9 -22.5 20.0 -1 300.0 14.52 -22.77 20.0 -1 300.0 13.78 -23.32 20.0 -1 300.0 12.41 -24.4 20.0 -1 300.0 12.1 -24.67 20.0 -1 300.0 11.79 -24.93 20.0 -1 300.0 11.22 -25.45 20.0 -1 300.0 10.96 -25.71 20.0 -1 300.0 10.71 -25.97 20.0 -1 300.0 10.25 -26.48 20.0 -1 300.0 10.04 -26.73 20.0 -1 300.0 9.85 -26.97 20.0 -1 300.0 9.67 -27.22 20.0 -1 300.0 9.51 -27.46 20.0 -1 300.0 9.36 -27.7 20.0 -1 300.0 9.23 -27.94 20.0 -1 300.0 9.12 -28.18 20.0 -1 300.0 9.02 -28.41 20.0 -1 300.0 8.94 -28.63 20.0 -1 300.0 8.87 -28.86 20.0 -1 300.0 8.83 -29.07 20.0 -1 300.0 8.8 -29.29 20.0 -1 300.0 8.78 -29.5 20.0 -1 300.0 8.78 -29.72 20.0 -1 300.0 8.8 -29.92 20.0 -1 300.0 8.83 -30.13 20.0 -1 300.0 8.88 -30.33 20.0 -1 300.0 8.95 -30.53 20.0 -1 300.0 9.03 -30.72 20.0 -1 300.0 9.13 -30.91 20.0 -1 300.0 9.24 -31.1 20.0 -1 300.0 9.36 -31.29 20.0 -1 300.0 9.51 -31.47 20.0 -1 300.0 9.66 -31.64 20.0 -1 300.0 9.83 -31.82 20.0 -1 300.0 10.02 -31.99 20.0 -1 300.0 10.21 -32.16 20.0 -1 300.0 10.43 -32.32 20.0 -1 300.0 10.65 -32.48 20.0 -1 300.0 10.88 -32.63 20.0 -1 300.0 11.39 -32.93 20.0 -1 300.0 11.66 -33.08 20.0 -1 300.0 11.95 -33.22 20.0 -1 300.0 12.54 -33.48 20.0 -1 300.0 12.85 -33.61 20.0 -1 300.0 13.16 -33.73 20.0 -1 300.0 13.82 -33.97 20.0 -1 300.0 14.16 -34.08 20.0 -1 300.0 14.5 -34.19 20.0 -1 300.0 15.21 -34.39 20.0 -1 300.0 15.57 -34.49 20.0 -1 300.0 15.93 -34.58 20.0 -1 300.0 16.66 -34.75 20.0 -1 300.0 17.03 -34.83 20.0 -1 300.0 17.4 -34.9 20.0 -1 300.0 17.77 -34.97 20.0 -1 300.0 18.13 -35.04 20.0 -1 300.0 18.5 -35.1 20.0 -1 300.0 18.86 -35.16 20.0 -1 300.0 19.59 -35.26 20.0 -1 300.0 19.94 -35.3 20.0 -1 300.0 20.29 -35.35 20.0 -1 300.0 20.63 -35.38 20.0 -1 300.0 20.97 -35.42 20.0 -1 300.0 21.3 -35.44 20.0 -1 300.0 21.63 -35.47 20.0 -1 300.0 21.95 -35.49 20.0 -1 300.0 22.26 -35.51 20.0 -1 300.0 22.56 -35.52 20.0 -1 300.0 22.85 -35.53 20.0 -1 300.0 23.13 -35.53 20.0 -1 300.0 23.4 -35.53 20.0 -1 300.0 23.66 -35.53 20.0 -1 300.0 23.9 -35.52 20.0 -1 300.0 24.14 -35.51 20.0 -1 300.0 24.36 -35.5 20.0 -1 300.0 24.56 -35.48 20.0 -1 300.0 24.75 -35.46 20.0 -1 300.0 24.92 -35.44 20.0 -1 300.0 25.08 -35.41 20.0 -1 300.0 25.23 -35.38 20.0 -1 300.0 25.36 -35.34 20.0 -1 300.0 25.49 -35.31 20.0 -1 300.0 25.6 -35.27 20.0 -1 300.0 25.69 -35.23 20.0 -1 300.0 25.78 -35.18 20.0 -1 300.0 25.85 -35.13 20.0 -1 300.0 25.9 -35.08 20.0 -1 300.0 25.94 -35.03 20.0 -1 300.0 25.97 -34.97 20.0 -1 300.0 25.99 -34.91 20.0 -1 300.0 25.99 -34.85 20.0 -1 300.0 25.97 -34.78 20.0 -1 300.0 25.94 -34.72 20.0 -1 300.0 25.9 -34.65 20.0 -1 300.0 25.84 -34.58 20.0 -1 300.0 25.77 -34.5 20.0 -1 300.0 25.68 -34.42 20.0 -1 300.0 25.59 -34.34 20.0 -1 300.0 25.47 -34.26 20.0 -1 300.0 25.34 -34.17 20.0 -1 300.0 25.2 -34.09 20.0 -1 300.0 24.88 -33.91 20.0 -1 300.0 24.7 -33.81 20.0 -1 300.0 24.51 -33.72 20.0 -1 300.0 24.09 -33.52 20.0 -1 300.0 23.86 -33.42 20.0 -1 300.0 23.61 -33.32 20.0 -1 300.0 23.09 -33.11 20.0 -1 300.0 21.93 -32.67 20.0 -1 300.0 19.2 -31.74 20.0 -1 300.0 12.95 -29.75 20.0 -1 300.0 12.53 -29.61 20.0 -1 300.0 12.12 -29.48 20.0 -1 300.0 11.3 -29.21 20.0 -1 300.0 9.75 -28.68 20.0 -1 300.0 9.38 -28.55 20.0 -1 300.0 9.03 -28.42 20.0 -1 300.0 8.34 -28.17 20.0 -1 300.0 7.1 -27.68 20.0 -1 300.0 6.83 -27.56 20.0 -1 300.0 6.56 -27.44 20.0 -1 300.0 6.07 -27.21 20.0 -1 300.0 5.85 -27.1 20.0 -1 300.0 5.64 -26.99 20.0 -1 300.0 5.27 -26.78 20.0 -1 300.0 5.11 -26.68 20.0 -1 300.0 4.96 -26.58 20.0 -1 300.0 4.83 -26.48 20.0 -1 300.0 4.72 -26.38 20.0 -1 300.0 4.62 -26.29 20.0 -1 300.0 4.54 -26.2 20.0 -1 300.0 4.48 -26.11 20.0 -1 300.0 4.43 -26.03 20.0 -1 300.0 4.4 -25.94 20.0 -1 300.0 4.38 -25.86 20.0 -1 300.0 4.38 -25.79 20.0 -1 300.0 4.4 -25.71 20.0 -1 300.0 4.44 -25.64 20.0 -1 300.0 4.49 -25.58 20.0 -1 300.0 4.56 -25.51 20.0 -1 300.0 4.64 -25.45 20.0 -1 300.0 4.74 -25.39 20.0 -1 300.0 4.85 -25.34 20.0 -1 300.0 4.98 -25.29 20.0 -1 300.0 5.13 -25.24 20.0 -1 300.0 5.29 -25.19 20.0 -1 300.0 5.46 -25.15 20.0 -1 300.0 5.65 -25.11 20.0 -1 300.0 5.85 -25.08 20.0 -1 300.0 6.06 -25.05 20.0 -1 300.0 6.29 -25.02 20.0 -1 300.0 6.53 -25.0 20.0 -1 300.0 6.78 -24.98 20.0 -1 300.0 7.04 -24.96 20.0 -1 300.0 7.31 -24.95 20.0 -1 300.0 7.6 -24.94 20.0 -1 300.0 7.89 -24.94 20.0 -1 300.0 8.19 -24.94 20.0 -1 300.0 8.5 -24.94 20.0 -1 300.0 8.82 -24.95 20.0 -1 300.0 9.15 -24.96 20.0 -1 300.0 9.48 -24.98 20.0 -1 300.0 9.82 -24.99 20.0 -1 300.0 10.16 -25.02 20.0 -1 300.0 10.51 -25.04 20.0 -1 300.0 10.84 -25.07 20.0 -1 300.0 11.17 -25.1 20.0 -1 300.0 11.51 -25.14 20.0 -1 300.0 11.84 -25.18 20.0 -1 300.0 12.18 -25.22 20.0 -1 300.0 12.52 -25.27 20.0 -1 300.0 13.2 -25.37 20.0 -1 300.0 13.53 -25.43 20.0 -1 300.0 13.87 -25.49 20.0 -1 300.0 14.2 -25.55 20.0 -1 300.0 14.54 -25.62 20.0 -1 300.0 14.86 -25.69 20.0 -1 300.0 15.19 -25.76 20.0 -1 300.0 15.82 -25.92 20.0 -1 300.0 16.13 -26.0 20.0 -1 300.0 16.44 -26.09 20.0 -1 300.0 16.74 -26.18 20.0 -1 300.0 17.03 -26.28 20.0 -1 300.0 17.31 -26.38 20.0 -1 300.0 17.59 -26.48 20.0 -1 300.0 18.11 -26.69 20.0 -1 300.0 18.36 -26.8 20.0 -1 300.0 18.6 -26.91 20.0 -1 300.0 18.83 -27.03 20.0 -1 300.0 19.05 -27.15 20.0 -1 300.0 19.26 -27.28 20.0 -1 300.0 19.46 -27.4 20.0 -1 300.0 19.64 -27.53 20.0 -1 300.0 19.82 -27.67 20.0 -1 300.0 19.98 -27.8 20.0 -1 300.0 20.13 -27.94 20.0 -1 300.0 20.26 -28.09 20.0 -1 300.0 20.39 -28.23 20.0 -1 300.0 20.5 -28.38 20.0 -1 300.0 20.59 -28.53 20.0 -1 300.0 20.68 -28.68 20.0 -1 300.0 20.75 -28.84 20.0 -1 300.0 20.8 -29.0 20.0 -1 300.0 20.84 -29.16 20.0 -1 300.0 20.87 -29.33 20.0 -1 300.0 20.88 -29.49 20.0 -1 300.0 20.88 -29.66 20.0 -1 300.0 20.86 -29.84 20.0 -1 300.0 20.83 -30.01 20.0 -1 300.0 20.78 -30.19 20.0 -1 300.0 20.72 -30.37 20.0 -1 300.0 20.64 -30.55 20.0 -1 300.0 20.56 -30.73 20.0 -1 300.0 20.45 -30.92 20.0 -1 300.0 20.33 -31.11 20.0 -1 300.0 20.2 -31.3 20.0 -1 300.0 20.05 -31.49 20.0 -1 300.0 19.89 -31.69 20.0 -1 300.0 19.72 -31.89 20.0 -1 300.0 19.53 -32.08 20.0 -1 300.0 19.12 -32.49 20.0 -1 300.0 18.89 -32.69 20.0 -1 300.0 18.66 -32.9 20.0 -1 300.0 18.14 -33.31 20.0 -1 300.0 17.87 -33.52 20.0 -1 300.0 17.59 -33.72 20.0 -1 300.0 17.01 -34.14 20.0 -1 300.0 15.72 -34.99 20.0 -1 300.0 12.8 -36.73 20.0 -1 300.0 12.41 -36.95 20.0 -1 300.0 12.02 -37.17 20.0 -1 300.0 11.22 -37.61 20.0 -1 300.0 9.62 -38.49 20.0 -1 300.0 6.46 -40.24 20.0 -1 300.0 6.07 -40.45 20.0 -1 300.0 5.7 -40.67 20.0 -1 300.0 4.96 -41.1 20.0 -1 300.0 3.57 -41.94 20.0 -1 300.0 3.24 -42.15 20.0 -1 300.0 2.92 -42.36 20.0 -1 300.0 2.3 -42.77 20.0 -1 300.0 1.19 -43.57 20.0 -1 300.0 0.94 -43.76 20.0 -1 300.0 0.71 -43.96 20.0 -1 300.0 0.26 -44.34 20.0 -1 300.0 0.06 -44.53 20.0 -1 300.0 -0.13 -44.72 20.0 -1 300.0 -0.47 -45.09 20.0 -1 300.0 -0.62 -45.27 20.0 -1 300.0 -0.76 -45.44 20.0 -1 300.0 -0.88 -45.62 20.0 -1 300.0 -0.99 -45.79 20.0 -1 300.0 -1.09 -45.97 20.0 -1 300.0 -1.17 -46.13 20.0 -1 300.0 -1.24 -46.3 20.0 -1 300.0 -1.3 -46.47 20.0 -1 300.0 -1.34 -46.64 20.0 -1 300.0 -1.37 -46.81 20.0 -1 300.0 -1.38 -46.98 20.0 -1 300.0 -1.38 -47.15 20.0 -1 300.0 -1.36 -47.31 20.0 -1 300.0 -1.32 -47.47 20.0 -1 300.0 -1.27 -47.62 20.0 -1 300.0 -1.2 -47.77 20.0 -1 300.0 -1.11 -47.92 20.0 -1 300.0 -1.01 -48.07 20.0 -1 300.0 -0.9 -48.21 20.0 -1 300.0 -0.77 -48.35 20.0 -1 300.0 -0.63 -48.48 20.0 -1 300.0 -0.47 -48.61 20.0 -1 300.0 -0.29 -48.74 20.0 -1 300.0 -0.11 -48.86 20.0 -1 300.0 0.09 -48.98 20.0 -1 300.0 0.3 -49.1 20.0 -1 300.0 0.53 -49.21 20.0 -1 300.0 0.77 -49.31 20.0 -1 300.0 1.01 -49.42 20.0 -1 300.0 1.27 -49.52 20.0 -1 300.0 1.82 -49.7 20.0 -1 300.0 2.11 -49.79 20.0 -1 300.0 2.41 -49.88 20.0 -1 300.0 2.71 -49.95 20.0 -1 300.0 3.03 -50.03 20.0 -1 300.0 3.35 -50.1 20.0 -1 300.0 3.67 -50.17 20.0 -1 300.0 4.0 -50.23 20.0 -1 300.0 4.34 -50.29 20.0 -1 300.0 4.68 -50.34 20.0 -1 300.0 5.03 -50.39 20.0 -1 300.0 5.38 -50.44 20.0 -1 300.0 5.73 -50.48 20.0 -1 300.0 6.08 -50.51 20.0 -1 300.0 6.43 -50.55 20.0 -1 300.0 6.79 -50.57 20.0 -1 300.0 7.14 -50.6 20.0 -1 300.0 7.49 -50.62 20.0 -1 300.0 7.84 -50.63 20.0 -1 300.0 8.19 -50.64 20.0 -1 300.0 8.54 -50.65 20.0 -1 300.0 8.88 -50.65 20.0 -1 300.0 9.22 -50.65 20.0 -1 300.0 9.55 -50.65 20.0 -1 300.0 9.88 -50.63 20.0 -1 300.0 10.2 -50.62 20.0 -1 300.0 10.52 -50.6 20.0 -1 300.0 10.82 -50.58 20.0 -1 300.0 11.12 -50.55 20.0 -1 300.0 11.41 -50.52 20.0 -1 300.0 11.69 -50.49 20.0 -1 300.0 11.96 -50.45 20.0 -1 300.0 12.22 -50.4 20.0 -1 300.0 12.47 -50.36 20.0 -1 300.0 12.71 -50.3 20.0 -1 300.0 12.94 -50.25 20.0 -1 300.0 13.15 -50.19 20.0 -1 300.0 13.36 -50.13 20.0 -1 300.0 13.55 -50.06 20.0 -1 300.0 13.72 -49.99 20.0 -1 300.0 13.88 -49.92 20.0 -1 300.0 14.02 -49.84 20.0 -1 300.0 14.14 -49.77 20.0 -1 300.0 14.26 -49.69 20.0 -1 300.0 14.36 -49.6 20.0 -1 300.0 14.44 -49.52 20.0 -1 300.0 14.51 -49.43 20.0 -1 300.0 14.57 -49.34 20.0 -1 300.0 14.62 -49.24 20.0 -1 300.0 14.64 -49.15 20.0 -1 300.0 14.66 -49.05 20.0 -1 300.0 14.66 -48.94 20.0 -1 300.0 14.65 -48.84 20.0 -1 300.0 14.63 -48.73 20.0 -1 300.0 14.58 -48.62 20.0 -1 300.0 14.53 -48.5 20.0 -1 300.0 14.46 -48.39 20.0 -1 300.0 14.38 -48.27 20.0 -1 300.0 14.28 -48.15 20.0 -1 300.0 14.17 -48.02 20.0 -1 300.0 14.04 -47.9 20.0 -1 300.0 13.9 -47.77 20.0 -1 300.0 13.75 -47.63 20.0 -1 300.0 13.4 -47.37 20.0 -1 300.0 13.21 -47.23 20.0 -1 300.0 13.0 -47.09 20.0 -1 300.0 12.55 -46.8 20.0 -1 300.0 11.5 -46.21 20.0 -1 300.0 11.21 -46.06 20.0 -1 300.0 10.92 -45.9 20.0 -1 300.0 10.29 -45.59 20.0 -1 300.0 8.92 -44.95 20.0 -1 300.0 5.87 -43.61 20.0 -1 300.0 5.47 -43.44 20.0 -1 300.0 5.06 -43.27 20.0 -1 300.0 4.25 -42.93 20.0 -1 300.0 2.6 -42.24 20.0 -1 300.0 -0.6 -40.87 20.0 -1 300.0 -1.02 -40.68 20.0 -1 300.0 -1.44 -40.49 20.0 -1 300.0 -2.26 -40.12 20.0 -1 300.0 -3.76 -39.38 20.0 -1 300.0 -4.11 -39.2 20.0 -1 300.0 -4.45 -39.02 20.0 -1 300.0 -5.08 -38.66 20.0 -1 300.0 -5.38 -38.49 20.0 -1 300.0 -5.66 -38.32 20.0 -1 300.0 -6.18 -37.98 20.0 -1 300.0 -6.42 -37.81 20.0 -1 300.0 -6.64 -37.65 20.0 -1 300.0 -6.84 -37.48 20.0 -1 300.0 -7.03 -37.32 20.0 -1 300.0 -7.2 -37.16 20.0 -1 300.0 -7.35 -37.01 20.0 -1 300.0 -7.49 -36.86 20.0 -1 300.0 -7.61 -36.71 20.0 -1 300.0 -7.71 -36.56 20.0 -1 300.0 -7.79 -36.41 20.0 -1 300.0 -7.86 -36.27 20.0 -1 300.0 -7.9 -36.13 20.0 -1 300.0 -7.93 -36.0 20.0 -1 300.0 -7.95 -35.86 20.0 -1 300.0 -7.94 -35.73 20.0 -1 300.0 -7.92 -35.61 20.0 -1 300.0 -7.88 -35.48 20.0 -1 300.0 -7.82 -35.36 20.0 -1 300.0 -7.74 -35.25 20.0 -1 300.0 -7.65 -35.13 20.0 -1 300.0 -7.54 -35.02 20.0 -1 300.0 -7.42 -34.92 20.0 -1 300.0 -7.28 -34.81 20.0 -1 300.0 -7.12 -34.72 20.0 -1 300.0 -6.95 -34.62 20.0 -1 300.0 -6.76 -34.53 20.0 -1 300.0 -6.56 -34.44 20.0 -1 300.0 -6.34 -34.36 20.0 -1 300.0 -6.12 -34.28 20.0 -1 300.0 -5.87 -34.2 20.0 -1 300.0 -5.62 -34.13 20.0 -1 300.0 -5.35 -34.06 20.0 -1 300.0 -5.08 -33.99 20.0 -1 300.0 -4.79 -33.93 20.0 -1 300.0 -4.49 -33.88 20.0 -1 300.0 -4.18 -33.82 20.0 -1 300.0 -3.86 -33.77 20.0 -1 300.0 -3.54 -33.73 20.0 -1 300.0 -3.21 -33.69 20.0 -1 300.0 -2.87 -33.66 20.0 -1 300.0 -2.52 -33.62 20.0 -1 300.0 -2.17 -33.6 20.0 -1 300.0 -1.82 -33.57 20.0 -1 300.0 -1.46 -33.55 20.0 -1 300.0 -1.1 -33.54 20.0 -1 300.0 -0.73 -33.53 20.0 -1 300.0 -0.37 -33.52 20.0 -1 300.0 0.0 -33.52 20.0 -0 300.0 0.0 -33.52 6.0 -0 300.0 37.56 12.33 6.0 -1 300.0 37.56 12.33 -1.0 -1 300.0 37.56 0.88 -1.0 -1 300.0 49.01 0.88 -1.0 -1 300.0 49.01 12.33 -1.0 -1 300.0 37.56 12.33 -1.0 -0 300.0 37.56 12.33 6.0 -0 300.0 37.56 0.88 6.0 -1 300.0 37.56 0.88 -1.0 -1 300.0 37.56 -10.57 -1.0 -1 300.0 49.01 -10.57 -1.0 -1 300.0 49.01 0.88 -1.0 -1 300.0 37.56 0.88 -1.0 -0 300.0 37.56 0.88 6.0 -0 300.0 49.01 12.33 6.0 -1 300.0 49.01 12.33 -1.0 -1 300.0 52.08 15.01 -1.0 -0 300.0 52.08 15.01 6.0 -0 300.0 49.01 0.88 6.0 -1 300.0 49.01 0.88 -1.0 -1 300.0 52.08 6.21 -1.0 -1 300.0 52.08 15.01 -1.0 -1 300.0 43.29 15.01 -1.0 -1 300.0 37.56 12.33 -1.0 -0 300.0 37.56 12.33 6.0 -0 300.0 49.01 -10.57 6.0 -1 300.0 49.01 -10.57 -1.0 -1 300.0 52.08 -2.58 -1.0 -1 300.0 52.08 6.21 -1.0 -1 300.0 49.01 0.88 -1.0 -0 300.0 49.01 0.88 6.0 -0 300.0 49.01 0.88 20.0 -0 300.0 0.0 0.0 20.0 -0 300.0 0.0 0.0 20.0 diff --git a/test/matlab/matlab_convert.py b/test/matlab/matlab_convert.py deleted file mode 100755 index cf750ac..0000000 --- a/test/matlab/matlab_convert.py +++ /dev/null @@ -1,270 +0,0 @@ -#!/usr/bin/env python -"""\ -The MIT License (MIT) - -Copyright (c) 2014 Sungeun K. Jeon - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. ----------------------------------------------------------------------------------------- -""" -"""\ -G-code preprocessor for the grbl_sim.m MATLAB script. Parses the g-code program to a -specific file format for the MATLAB script to use. Based on PreGrbl by @chamnit. - -How to use: When running this python script, it will process the g-code program under -the filename "test.gcode" (may be changed below) and produces a file called "matlab.gcode" -that the grbl_sim.m MATLAB script will search for and execute. -""" - -import re -from math import * -from copy import * - -# -= SETTINGS =- -filein = 'test.gcode' # Input file name -fileout = 'matlab.gcode' # Output file name -ndigits_in = 4 # inch significant digits after '.' -ndigits_mm = 2 # mm significant digits after '.' -# mm_per_arc_segment = 0.38 # mm per arc segment -arc_tolerance = 0.00005*25.4 -n_arc_correction = 20 -inch2mm = 25.4 # inch to mm conversion scalar -verbose = False # Verbose flag to show all progress -remove_unsupported = True # Removal flag for all unsupported statements - -# Initialize parser state -gc = { 'current_xyz' : [0,0,0], - 'feed_rate' : 0, # F0 - 'motion_mode' : 'SEEK', # G00 - 'plane_axis' : [0,1,2], # G17 - 'inches_mode' : False, # G21 - 'inverse_feedrate_mode' : False, # G94 - 'absolute_mode' : True} # G90 - -def unit_conv(val) : # Converts value to mm - if gc['inches_mode'] : val *= inch2mm - return(val) - -def fout_conv(val) : # Returns converted value as rounded string for output file. - if gc['inches_mode'] : return( str(round(val/inch2mm,ndigits_in)) ) - else : return( str(round(val,ndigits_mm)) ) - -# Open g-code file -fin = open(filein,'r'); -fout = open(fileout,'w'); - -# Iterate through g-code file -l_count = 0 -for line in fin: - l_count += 1 # Iterate line counter - - # Strip comments/spaces/tabs/new line and capitalize. Comment MSG not supported. - block = re.sub('\s|\(.*?\)','',line).upper() - block = re.sub('\\\\','',block) # Strip \ block delete character - block = re.sub('%','',block) # Strip % program start/stop character - - if len(block) == 0 : # Ignore empty blocks - - print "Skipping: " + line.strip() - - else : # Process valid g-code clean block. Assumes no block delete characters or comments - - g_cmd = re.findall(r'[^0-9\.\-]+',block) # Extract block command characters - g_num = re.findall(r'[0-9\.\-]+',block) # Extract block numbers - - # G-code block error checks - # if len(g_cmd) != len(g_num) : print block; raise Exception('Invalid block. Unbalanced word and values.') - if 'N' in g_cmd : - if g_cmd[0]!='N': raise Exception('Line number must be first command in line.') - if g_cmd.count('N') > 1: raise Exception('More than one line number in block.') - g_cmd = g_cmd[1:] # Remove line number word - g_num = g_num[1:] - # Block item repeat checks? (0<=n'M'<5, G/M modal groups) - - # Initialize block state - blk = { 'next_action' : 'DEFAULT', - 'absolute_override' : False, - 'target_xyz' : deepcopy(gc['current_xyz']), - 'offset_ijk' : [0,0,0], - 'radius_mode' : False, - 'unsupported': [] } - - # Pass 1 - for cmd,num in zip(g_cmd,g_num) : - fnum = float(num) - inum = int(fnum) - if cmd is 'G' : - if inum is 0 : gc['motion_mode'] = 'SEEK' - elif inum is 1 : gc['motion_mode'] = 'LINEAR' - elif inum is 2 : gc['motion_mode'] = 'CW_ARC' - elif inum is 3 : gc['motion_mode'] = 'CCW_ARC' - elif inum is 4 : blk['next_action'] = 'DWELL' - elif inum is 17 : gc['plane_axis'] = [0,1,2] # Select XY Plane - elif inum is 18 : gc['plane_axis'] = [0,2,1] # Select XZ Plane - elif inum is 19 : gc['plane_axis'] = [1,2,0] # Select YZ Plane - elif inum is 20 : gc['inches_mode'] = True - elif inum is 21 : gc['inches_mode'] = False - elif inum in [28,30] : blk['next_action'] = 'GO_HOME' - elif inum is 53 : blk['absolute_override'] = True - elif inum is 54 : pass - elif inum is 80 : gc['motion_mode'] = 'MOTION_CANCEL' - elif inum is 90 : gc['absolute_mode'] = True - elif inum is 91 : gc['absolute_mode'] = False - elif inum is 92 : blk['next_action'] = 'SET_OFFSET' - elif inum is 93 : gc['inverse_feedrate_mode'] = True - elif inum is 94 : gc['inverse_feedrate_mode'] = False - else : - print 'Unsupported command ' + cmd + num + ' on line ' + str(l_count) - if remove_unsupported : blk['unsupported'].append(zip(g_cmd,g_num).index((cmd,num))) - elif cmd is 'M' : - if inum in [0,1] : pass # Program Pause - elif inum in [2,30,60] : pass # Program Completed - elif inum is 3 : pass # Spindle Direction 1 - elif inum is 4 : pass # Spindle Direction -1 - elif inum is 5 : pass # Spindle Direction 0 - else : - print 'Unsupported command ' + cmd + num + ' on line ' + str(l_count) - if remove_unsupported : blk['unsupported'].append(zip(g_cmd,g_num).index((cmd,num))) - elif cmd is 'T' : pass # Tool Number - - # Pass 2 - for cmd,num in zip(g_cmd,g_num) : - fnum = float(num) - if cmd is 'F' : gc['feed_rate'] = unit_conv(fnum) # Feed Rate - elif cmd in ['I','J','K'] : blk['offset_ijk'][ord(cmd)-ord('I')] = unit_conv(fnum) # Arc Center Offset - elif cmd is 'N' : pass - elif cmd is 'P' : p = fnum # Misc value parameter - elif cmd is 'R' : r = unit_conv(fnum); blk['radius_mode'] = True # Arc Radius Mode - elif cmd is 'S' : pass # Spindle Speed - elif cmd in ['X','Y','Z'] : # Target Coordinates - if (gc['absolute_mode'] | blk['absolute_override']) : - blk['target_xyz'][ord(cmd)-ord('X')] = unit_conv(fnum) - else : - blk['target_xyz'][ord(cmd)-ord('X')] += unit_conv(fnum) - - # Execute actions - if blk['next_action'] is 'GO_HOME' : - gc['current_xyz'] = deepcopy(blk['target_xyz']) # Update position - elif blk['next_action'] is 'SET_OFFSET' : - pass - elif blk['next_action'] is 'DWELL' : - if p < 0 : raise Exception('Dwell time negative.') - else : # 'DEFAULT' - if gc['motion_mode'] is 'SEEK' : - fout.write('0 '+fout_conv(gc['feed_rate'])) - fout.write(' '+fout_conv(blk['target_xyz'][0])) - fout.write(' '+fout_conv(blk['target_xyz'][1])) - fout.write(' '+fout_conv(blk['target_xyz'][2])) - fout.write('\n') - gc['current_xyz'] = deepcopy(blk['target_xyz']) # Update position - elif gc['motion_mode'] is 'LINEAR' : - fout.write('1 '+fout_conv(gc['feed_rate'])) - fout.write(' '+fout_conv(blk['target_xyz'][0])) - fout.write(' '+fout_conv(blk['target_xyz'][1])) - fout.write(' '+fout_conv(blk['target_xyz'][2])) - fout.write('\n') - gc['current_xyz'] = deepcopy(blk['target_xyz']) # Update position - elif gc['motion_mode'] in ['CW_ARC','CCW_ARC'] : - axis = gc['plane_axis'] - - # Convert radius mode to ijk mode - if blk['radius_mode'] : - x = blk['target_xyz'][axis[0]]-gc['current_xyz'][axis[0]] - y = blk['target_xyz'][axis[1]]-gc['current_xyz'][axis[1]] - if not (x==0 and y==0) : raise Exception('Same target and current XYZ not allowed in arc radius mode.') - h_x2_div_d = -sqrt(4 * r*r - x*x - y*y)/hypot(x,y) - if isnan(h_x2_div_d) : raise Exception('Floating point error in arc conversion') - if gc['motion_mode'] is 'CCW_ARC' : h_x2_div_d = -h_x2_div_d - if r < 0 : h_x2_div_d = -h_x2_div_d - blk['offset_ijk'][axis[0]] = (x-(y*h_x2_div_d))/2; - blk['offset_ijk'][axis[1]] = (y+(x*h_x2_div_d))/2; - else : - radius = sqrt(blk['offset_ijk'][axis[0]]**2+blk['offset_ijk'][axis[1]]**2) - - center_axis0 = gc['current_xyz'][axis[0]]+blk['offset_ijk'][axis[0]] - center_axis1 = gc['current_xyz'][axis[1]]+blk['offset_ijk'][axis[1]] - linear_travel = blk['target_xyz'][axis[2]]-gc['current_xyz'][axis[2]] - r_axis0 = -blk['offset_ijk'][axis[0]] - r_axis1 = -blk['offset_ijk'][axis[1]] - rt_axis0 = blk['target_xyz'][axis[0]] - center_axis0; - rt_axis1 = blk['target_xyz'][axis[1]] - center_axis1; - clockwise_sign = 1 - if gc['motion_mode'] is 'CW_ARC' : clockwise_sign = -1 - - angular_travel = atan2(r_axis0*rt_axis1-r_axis1*rt_axis0, r_axis0*rt_axis0+r_axis1*rt_axis1) - if gc['motion_mode'] is 'CW_ARC' : - if angular_travel >= 0 : - angular_travel -= 2*pi - else : - if angular_travel <= 0 : - angular_travel += 2*pi - - millimeters_of_travel = sqrt((angular_travel*radius)**2 + abs(linear_travel)**2) - - mm_per_arc_segment = sqrt(4*(2*radius*arc_tolerance-arc_tolerance**2)) - segments = int(millimeters_of_travel/mm_per_arc_segment) - print segments - print l_count - theta_per_segment = angular_travel/segments - linear_per_segment = linear_travel/segments - cos_T = 1-0.5*theta_per_segment*theta_per_segment - sin_T = theta_per_segment-theta_per_segment**3/6 - print(fout_conv(mm_per_arc_segment)) - print theta_per_segment*180/pi - - arc_target = [0,0,0] - arc_target[axis[2]] = gc['current_xyz'][axis[2]] - - count = 0 - for i in range(1,segments+1) : - if i < segments : - if count < n_arc_correction : - r_axisi = r_axis0*sin_T + r_axis1*cos_T - r_axis0 = r_axis0*cos_T - r_axis1*sin_T - r_axis1 = deepcopy(r_axisi) - count += 1 - else : - cos_Ti = cos((i-1)*theta_per_segment) - sin_Ti = sin((i-1)*theta_per_segment) - print n_arc_correction*(r_axis0 -( -blk['offset_ijk'][axis[0]]*cos_Ti + blk['offset_ijk'][axis[1]]*sin_Ti)) - print n_arc_correction*(r_axis1 -( -blk['offset_ijk'][axis[0]]*sin_Ti - blk['offset_ijk'][axis[1]]*cos_Ti)) - cos_Ti = cos(i*theta_per_segment) - sin_Ti = sin(i*theta_per_segment) - r_axis0 = -blk['offset_ijk'][axis[0]]*cos_Ti + blk['offset_ijk'][axis[1]]*sin_Ti - r_axis1 = -blk['offset_ijk'][axis[0]]*sin_Ti - blk['offset_ijk'][axis[1]]*cos_Ti - count = 0 - arc_target[axis[0]] = center_axis0 + r_axis0 - arc_target[axis[1]] = center_axis1 + r_axis1 - arc_target[axis[2]] += linear_per_segment - else : - arc_target = deepcopy(blk['target_xyz']) # Last segment at target_xyz - # Write only changed variables. - fout.write('1 '+fout_conv(gc['feed_rate'])) - fout.write(' '+fout_conv(arc_target[0])) - fout.write(' '+fout_conv(arc_target[1])) - fout.write(' '+fout_conv(arc_target[2])) - fout.write('\n') - gc['current_xyz'] = deepcopy(arc_target) # Update position - - -print 'Done!' - -# Close files -fin.close() -fout.close() \ No newline at end of file diff --git a/test/matlab/test.gcode b/test/matlab/test.gcode deleted file mode 100644 index 3d9d56c..0000000 --- a/test/matlab/test.gcode +++ /dev/null @@ -1,2363 +0,0 @@ -(Braid.NC Test Program) -T1M6 -G17G21 -G0X0Y0 -G0Z6.000 -G0X37.560Y12.327Z6.000 -G1Z-1.000 F300 -G1Y0.876 -X49.011 -Y12.327 -X37.560 -G0Z6.000 -G0Y0.876 -G1Z-1.000 -G1Y-10.575 -X49.011 -Y0.876 -X37.560 -G0Z6.000 -G0X49.011Y12.327 -G1Z-1.000 -G1X52.084Y15.011 -G0Z6.000 -G0X49.011Y0.876 -G1Z-1.000 -G1X52.084Y6.213 -Y15.011 -X43.286 -X37.560Y12.327 -G0Z6.000 -G0X49.011Y-10.575 -G1Z-1.000 -G1X52.084Y-2.585 -Y6.213 -X49.011Y0.876 -G0Z6.000 -G0Z20.000 -G0X0.000Y0.000 -G1X-7.098Y-39.876 -X-10.296Y-38.118 -X-10.698Y-37.897 -X-11.099Y-37.676 -X-11.894Y-37.235 -X-13.448Y-36.356 -X-13.825Y-36.137 -X-14.197Y-35.919 -X-14.923Y-35.485 -X-16.288Y-34.625 -X-16.636Y-34.395 -X-16.973Y-34.165 -X-17.613Y-33.711 -X-17.915Y-33.486 -X-18.204Y-33.262 -X-18.743Y-32.821 -X-18.992Y-32.602 -X-19.227Y-32.386 -X-19.447Y-32.171 -X-19.652Y-31.959 -X-19.843Y-31.749 -X-20.017Y-31.540 -X-20.176Y-31.335 -X-20.320Y-31.131 -X-20.447Y-30.930 -X-20.558Y-30.731 -X-20.653Y-30.535 -X-20.731Y-30.341 -X-20.793Y-30.150 -X-20.838Y-29.961 -X-20.867Y-29.776 -X-20.879Y-29.593 -X-20.875Y-29.413 -X-20.854Y-29.236 -X-20.817Y-29.062 -X-20.764Y-28.891 -X-20.695Y-28.723 -X-20.610Y-28.559 -X-20.510Y-28.397 -X-20.394Y-28.239 -X-20.263Y-28.084 -X-20.117Y-27.932 -X-19.957Y-27.784 -X-19.782Y-27.639 -X-19.594Y-27.498 -X-19.392Y-27.360 -X-19.177Y-27.226 -X-18.950Y-27.095 -X-18.710Y-26.968 -X-18.459Y-26.845 -X-18.197Y-26.725 -X-17.924Y-26.609 -X-17.641Y-26.497 -X-17.349Y-26.389 -X-16.737Y-26.183 -X-16.419Y-26.086 -X-16.094Y-25.993 -X-15.763Y-25.904 -X-15.426Y-25.818 -X-15.083Y-25.737 -X-14.736Y-25.660 -X-14.030Y-25.516 -X-13.672Y-25.451 -X-13.313Y-25.389 -X-12.953Y-25.332 -X-12.591Y-25.278 -X-12.230Y-25.228 -X-11.870Y-25.182 -X-11.511Y-25.140 -X-11.155Y-25.103 -X-10.824Y-25.071 -X-10.497Y-25.043 -X-10.173Y-25.018 -X-9.853Y-24.996 -X-9.538Y-24.978 -X-9.228Y-24.964 -X-8.924Y-24.952 -X-8.625Y-24.944 -X-8.334Y-24.940 -X-8.049Y-24.939 -X-7.772Y-24.941 -X-7.504Y-24.946 -X-7.243Y-24.955 -X-6.992Y-24.967 -X-6.750Y-24.982 -X-6.518Y-25.000 -X-6.295Y-25.022 -X-6.084Y-25.047 -X-5.883Y-25.075 -X-5.694Y-25.106 -X-5.517Y-25.140 -X-5.351Y-25.177 -X-5.197Y-25.217 -X-5.057Y-25.260 -X-4.928Y-25.306 -X-4.813Y-25.355 -X-4.711Y-25.407 -X-4.623Y-25.461 -X-4.548Y-25.518 -X-4.487Y-25.578 -X-4.439Y-25.641 -X-4.406Y-25.707 -X-4.387Y-25.775 -X-4.382Y-25.845 -X-4.392Y-25.918 -X-4.416Y-25.994 -X-4.454Y-26.072 -X-4.506Y-26.152 -X-4.572Y-26.235 -X-4.653Y-26.320 -X-4.748Y-26.407 -X-4.857Y-26.496 -X-4.980Y-26.588 -X-5.117Y-26.681 -X-5.267Y-26.777 -X-5.431Y-26.874 -X-5.798Y-27.074 -X-6.001Y-27.177 -X-6.216Y-27.282 -X-6.683Y-27.496 -X-7.755Y-27.942 -X-8.049Y-28.057 -X-8.353Y-28.173 -X-8.990Y-28.409 -X-10.362Y-28.891 -X-10.753Y-29.024 -X-11.151Y-29.158 -X-11.968Y-29.428 -X-13.658Y-29.973 -X-17.113Y-31.067 -X-17.538Y-31.202 -X-17.959Y-31.337 -X-18.788Y-31.604 -X-20.370Y-32.127 -X-20.746Y-32.255 -X-21.113Y-32.382 -X-21.817Y-32.631 -X-23.093Y-33.111 -X-23.381Y-33.226 -X-23.656Y-33.339 -X-24.164Y-33.560 -X-24.397Y-33.667 -X-24.615Y-33.772 -X-25.005Y-33.974 -X-25.177Y-34.072 -X-25.332Y-34.167 -X-25.472Y-34.259 -X-25.595Y-34.349 -X-25.701Y-34.436 -X-25.791Y-34.520 -X-25.864Y-34.601 -X-25.920Y-34.679 -X-25.960Y-34.754 -X-25.982Y-34.826 -X-25.987Y-34.895 -X-25.976Y-34.961 -X-25.948Y-35.023 -X-25.903Y-35.082 -X-25.841Y-35.138 -X-25.763Y-35.190 -X-25.669Y-35.239 -X-25.559Y-35.284 -X-25.433Y-35.325 -X-25.291Y-35.363 -X-25.134Y-35.397 -X-24.963Y-35.428 -X-24.777Y-35.455 -X-24.577Y-35.477 -X-24.367Y-35.496 -X-24.144Y-35.511 -X-23.909Y-35.522 -X-23.661Y-35.529 -X-23.403Y-35.532 -X-23.133Y-35.532 -X-22.853Y-35.527 -X-22.563Y-35.519 -X-22.263Y-35.506 -X-21.955Y-35.490 -X-21.638Y-35.470 -X-21.313Y-35.445 -X-20.981Y-35.416 -X-20.643Y-35.384 -X-20.299Y-35.347 -X-19.949Y-35.306 -X-19.595Y-35.261 -X-19.237Y-35.212 -X-18.875Y-35.158 -X-18.511Y-35.101 -X-18.145Y-35.039 -X-17.777Y-34.973 -X-17.041Y-34.829 -X-16.673Y-34.751 -X-16.306Y-34.668 -X-15.580Y-34.491 -X-15.222Y-34.396 -X-14.867Y-34.297 -X-14.172Y-34.086 -X-13.833Y-33.975 -X-13.501Y-33.859 -X-13.176Y-33.740 -X-12.858Y-33.616 -X-12.548Y-33.488 -X-12.248Y-33.357 -X-11.675Y-33.082 -X-11.404Y-32.938 -X-11.144Y-32.791 -X-10.896Y-32.639 -X-10.659Y-32.484 -X-10.435Y-32.326 -X-10.223Y-32.163 -X-10.025Y-31.997 -X-9.840Y-31.827 -X-9.669Y-31.653 -X-9.512Y-31.476 -X-9.370Y-31.295 -X-9.242Y-31.111 -X-9.130Y-30.923 -X-9.033Y-30.732 -X-8.951Y-30.538 -X-8.885Y-30.340 -X-8.835Y-30.139 -X-8.801Y-29.934 -X-8.782Y-29.727 -X-8.780Y-29.517 -X-8.794Y-29.303 -X-8.825Y-29.087 -X-8.871Y-28.867 -X-8.934Y-28.645 -X-9.006Y-28.435 -X-9.093Y-28.223 -X-9.194Y-28.008 -X-9.308Y-27.792 -X-9.435Y-27.573 -X-9.577Y-27.352 -X-9.898Y-26.903 -X-10.078Y-26.676 -X-10.271Y-26.446 -X-10.693Y-25.982 -X-10.922Y-25.748 -X-11.162Y-25.511 -X-11.675Y-25.034 -X-11.948Y-24.793 -X-12.230Y-24.550 -X-12.824Y-24.061 -X-14.114Y-23.068 -X-17.000Y-21.038 -X-17.380Y-20.782 -X-17.762Y-20.525 -X-18.532Y-20.010 -X-20.077Y-18.979 -X-20.462Y-18.721 -X-20.845Y-18.464 -X-21.602Y-17.949 -X-23.072Y-16.925 -X-23.427Y-16.671 -X-23.776Y-16.417 -X-24.454Y-15.911 -X-25.717Y-14.911 -X-26.011Y-14.664 -X-26.295Y-14.418 -X-26.833Y-13.930 -X-27.086Y-13.688 -X-27.328Y-13.447 -X-27.777Y-12.971 -X-28.000Y-12.715 -X-28.209Y-12.461 -X-28.404Y-12.210 -X-28.583Y-11.961 -X-28.746Y-11.713 -X-28.894Y-11.469 -X-29.026Y-11.226 -X-29.142Y-10.986 -X-29.242Y-10.749 -X-29.325Y-10.514 -X-29.391Y-10.281 -X-29.441Y-10.052 -X-29.475Y-9.825 -X-29.491Y-9.601 -X-29.491Y-9.380 -X-29.475Y-9.162 -X-29.441Y-8.947 -X-29.391Y-8.735 -X-29.325Y-8.526 -X-29.242Y-8.320 -X-29.144Y-8.118 -X-29.029Y-7.919 -X-28.899Y-7.723 -X-28.753Y-7.531 -X-28.592Y-7.342 -X-28.416Y-7.156 -X-28.226Y-6.974 -X-28.022Y-6.796 -X-27.804Y-6.621 -X-27.572Y-6.450 -X-27.071Y-6.119 -X-26.802Y-5.959 -X-26.522Y-5.803 -X-25.929Y-5.502 -X-25.617Y-5.358 -X-25.296Y-5.217 -X-24.628Y-4.948 -X-24.283Y-4.819 -X-23.930Y-4.694 -X-23.207Y-4.457 -X-22.838Y-4.344 -X-22.465Y-4.236 -X-21.707Y-4.031 -X-21.325Y-3.935 -X-20.941Y-3.842 -X-20.170Y-3.670 -X-19.786Y-3.590 -X-19.402Y-3.515 -X-18.642Y-3.375 -X-18.266Y-3.312 -X-17.894Y-3.252 -X-17.527Y-3.197 -X-17.164Y-3.145 -X-16.808Y-3.098 -X-16.459Y-3.055 -X-16.116Y-3.015 -X-15.781Y-2.980 -X-15.477Y-2.951 -X-15.179Y-2.925 -X-14.891Y-2.902 -X-14.611Y-2.883 -X-14.340Y-2.867 -X-14.078Y-2.855 -X-13.827Y-2.845 -X-13.586Y-2.839 -X-13.355Y-2.837 -X-13.136Y-2.837 -X-12.929Y-2.841 -X-12.733Y-2.848 -X-12.549Y-2.858 -X-12.378Y-2.871 -X-12.220Y-2.888 -X-12.074Y-2.907 -X-11.942Y-2.929 -X-11.823Y-2.955 -X-11.717Y-2.983 -X-11.626Y-3.014 -X-11.548Y-3.048 -X-11.484Y-3.084 -X-11.435Y-3.124 -X-11.400Y-3.166 -X-11.379Y-3.210 -X-11.372Y-3.258 -X-11.380Y-3.308 -X-11.403Y-3.360 -X-11.440Y-3.415 -X-11.491Y-3.472 -X-11.556Y-3.532 -X-11.636Y-3.594 -X-11.729Y-3.658 -X-11.837Y-3.724 -X-11.959Y-3.793 -X-12.094Y-3.863 -X-12.242Y-3.936 -X-12.404Y-4.010 -X-12.767Y-4.165 -X-12.967Y-4.245 -X-13.179Y-4.327 -X-13.639Y-4.495 -X-14.691Y-4.850 -X-14.979Y-4.942 -X-15.277Y-5.036 -X-15.897Y-5.225 -X-17.230Y-5.617 -X-20.146Y-6.431 -X-20.516Y-6.532 -X-20.887Y-6.634 -X-21.630Y-6.837 -X-23.106Y-7.241 -X-25.895Y-8.028 -X-26.218Y-8.123 -X-26.535Y-8.218 -X-27.145Y-8.403 -X-28.260Y-8.760 -X-28.514Y-8.846 -X-28.759Y-8.930 -X-29.214Y-9.095 -X-29.425Y-9.175 -X-29.624Y-9.253 -X-29.986Y-9.404 -X-30.149Y-9.477 -X-30.298Y-9.548 -X-30.435Y-9.617 -X-30.559Y-9.684 -X-30.669Y-9.749 -X-30.766Y-9.812 -X-30.849Y-9.872 -X-30.918Y-9.931 -X-30.974Y-9.987 -X-31.016Y-10.041 -X-31.043Y-10.092 -X-31.057Y-10.141 -X-31.057Y-10.188 -X-31.043Y-10.232 -X-31.015Y-10.273 -X-30.972Y-10.312 -X-30.916Y-10.349 -X-30.847Y-10.382 -X-30.763Y-10.413 -X-30.666Y-10.441 -X-30.556Y-10.466 -X-30.432Y-10.489 -X-30.295Y-10.508 -X-30.146Y-10.525 -X-29.984Y-10.539 -X-29.809Y-10.549 -X-29.622Y-10.557 -X-29.424Y-10.562 -X-29.214Y-10.563 -X-28.992Y-10.562 -X-28.760Y-10.557 -X-28.517Y-10.549 -X-28.242Y-10.537 -X-27.955Y-10.521 -X-27.657Y-10.501 -X-27.349Y-10.477 -X-27.031Y-10.450 -X-26.703Y-10.418 -X-26.366Y-10.383 -X-26.021Y-10.343 -X-25.668Y-10.300 -X-25.308Y-10.253 -X-24.568Y-10.146 -X-24.191Y-10.086 -X-23.808Y-10.023 -X-23.032Y-9.883 -X-22.640Y-9.807 -X-22.245Y-9.728 -X-21.453Y-9.556 -X-21.057Y-9.463 -X-20.662Y-9.367 -X-19.876Y-9.162 -X-19.487Y-9.054 -X-19.101Y-8.941 -X-18.343Y-8.704 -X-17.972Y-8.579 -X-17.606Y-8.450 -X-16.896Y-8.180 -X-16.552Y-8.040 -X-16.217Y-7.895 -X-15.574Y-7.594 -X-15.268Y-7.438 -X-14.972Y-7.277 -X-14.414Y-6.946 -X-14.153Y-6.774 -X-13.905Y-6.599 -X-13.669Y-6.420 -X-13.447Y-6.237 -X-13.239Y-6.051 -X-13.044Y-5.862 -X-12.864Y-5.669 -X-12.699Y-5.472 -X-12.549Y-5.272 -X-12.414Y-5.069 -X-12.294Y-4.862 -X-12.190Y-4.652 -X-12.102Y-4.439 -X-12.030Y-4.223 -X-11.975Y-4.003 -X-11.935Y-3.781 -X-11.911Y-3.555 -X-11.904Y-3.327 -X-11.914Y-3.096 -X-11.939Y-2.862 -X-11.981Y-2.625 -X-12.038Y-2.386 -X-12.112Y-2.144 -X-12.202Y-1.899 -X-12.300Y-1.669 -X-12.412Y-1.436 -X-12.537Y-1.201 -X-12.675Y-0.965 -X-12.826Y-0.726 -X-12.990Y-0.486 -X-13.355Y0.001 -X-13.555Y0.246 -X-13.768Y0.494 -X-14.226Y0.993 -X-15.266Y2.009 -X-15.550Y2.266 -X-15.842Y2.524 -X-16.451Y3.043 -X-17.752Y4.093 -X-20.572Y6.219 -X-20.935Y6.486 -X-21.298Y6.753 -X-22.024Y7.287 -X-23.456Y8.353 -X-23.807Y8.618 -X-24.154Y8.883 -X-24.835Y9.411 -X-26.125Y10.458 -X-26.431Y10.717 -X-26.728Y10.975 -X-27.297Y11.489 -X-27.568Y11.744 -X-27.830Y11.997 -X-28.322Y12.500 -X-28.552Y12.749 -X-28.771Y12.997 -X-28.978Y13.243 -X-29.174Y13.487 -X-29.357Y13.729 -X-29.528Y13.970 -X-29.686Y14.209 -X-29.831Y14.446 -X-29.974Y14.700 -X-30.101Y14.953 -X-30.212Y15.202 -X-30.307Y15.449 -X-30.385Y15.694 -X-30.447Y15.936 -X-30.492Y16.175 -X-30.521Y16.411 -X-30.532Y16.644 -X-30.527Y16.874 -X-30.505Y17.102 -X-30.466Y17.326 -X-30.411Y17.547 -X-30.338Y17.765 -X-30.249Y17.980 -X-30.144Y18.191 -X-30.022Y18.399 -X-29.884Y18.603 -X-29.730Y18.805 -X-29.561Y19.002 -X-29.376Y19.196 -X-29.176Y19.386 -X-28.962Y19.573 -X-28.733Y19.756 -X-28.490Y19.935 -X-28.233Y20.111 -X-27.964Y20.282 -X-27.681Y20.450 -X-27.386Y20.614 -X-27.080Y20.774 -X-26.434Y21.081 -X-26.096Y21.229 -X-25.748Y21.373 -X-25.025Y21.648 -X-24.652Y21.780 -X-24.272Y21.907 -X-23.493Y22.149 -X-23.095Y22.264 -X-22.693Y22.375 -X-21.877Y22.583 -X-21.466Y22.681 -X-21.053Y22.775 -X-20.223Y22.949 -X-19.809Y23.030 -X-19.396Y23.107 -X-18.575Y23.247 -X-18.169Y23.311 -X-17.767Y23.371 -X-16.977Y23.478 -X-16.591Y23.525 -X-16.211Y23.568 -X-15.838Y23.606 -X-15.473Y23.641 -X-15.116Y23.671 -X-14.769Y23.698 -X-14.430Y23.720 -X-14.102Y23.739 -X-13.791Y23.753 -X-13.490Y23.763 -X-13.200Y23.769 -X-12.922Y23.772 -X-12.657Y23.771 -X-12.404Y23.766 -X-12.164Y23.758 -X-11.937Y23.746 -X-11.724Y23.730 -X-11.525Y23.711 -X-11.340Y23.688 -X-11.171Y23.662 -X-11.016Y23.633 -X-10.876Y23.600 -X-10.752Y23.564 -X-10.643Y23.524 -X-10.549Y23.481 -X-10.472Y23.435 -X-10.411Y23.386 -X-10.365Y23.334 -X-10.336Y23.279 -X-10.323Y23.221 -X-10.326Y23.161 -X-10.344Y23.097 -X-10.379Y23.030 -X-10.430Y22.961 -X-10.497Y22.889 -X-10.579Y22.815 -X-10.676Y22.738 -X-10.789Y22.659 -X-10.917Y22.577 -X-11.060Y22.493 -X-11.217Y22.407 -X-11.389Y22.318 -X-11.773Y22.135 -X-11.985Y22.041 -X-12.210Y21.945 -X-12.697Y21.747 -X-12.958Y21.645 -X-13.230Y21.542 -X-13.806Y21.331 -X-15.066Y20.894 -X-15.401Y20.782 -X-15.742Y20.670 -X-16.442Y20.441 -X-17.896Y19.977 -X-20.868Y19.035 -X-21.208Y18.926 -X-21.545Y18.817 -X-22.208Y18.600 -X-23.472Y18.173 -X-23.772Y18.068 -X-24.066Y17.964 -X-24.629Y17.759 -X-25.650Y17.361 -X-25.881Y17.265 -X-26.101Y17.170 -X-26.509Y16.984 -X-26.696Y16.893 -X-26.871Y16.804 -X-27.184Y16.631 -X-27.322Y16.547 -X-27.447Y16.465 -X-27.559Y16.385 -X-27.658Y16.306 -X-27.743Y16.230 -X-27.815Y16.156 -X-27.873Y16.084 -X-27.917Y16.014 -X-27.947Y15.946 -X-27.963Y15.880 -X-27.965Y15.817 -X-27.953Y15.756 -X-27.927Y15.697 -X-27.887Y15.641 -X-27.832Y15.588 -X-27.764Y15.537 -X-27.681Y15.488 -X-27.585Y15.442 -X-27.475Y15.399 -X-27.351Y15.358 -X-27.214Y15.321 -X-27.063Y15.286 -X-26.899Y15.253 -X-26.723Y15.224 -X-26.533Y15.198 -X-26.332Y15.174 -X-26.118Y15.154 -X-25.892Y15.136 -X-25.654Y15.122 -X-25.405Y15.110 -X-25.145Y15.102 -X-24.875Y15.097 -X-24.594Y15.095 -X-24.304Y15.096 -X-24.004Y15.100 -X-23.694Y15.107 -X-23.377Y15.118 -X-23.051Y15.132 -X-22.717Y15.149 -X-22.376Y15.170 -X-21.998Y15.196 -X-21.613Y15.226 -X-21.221Y15.260 -X-20.822Y15.298 -X-20.418Y15.340 -X-20.010Y15.385 -X-19.180Y15.489 -X-18.761Y15.547 -X-18.339Y15.609 -X-17.492Y15.744 -X-17.067Y15.818 -X-16.644Y15.896 -X-15.800Y16.064 -X-15.382Y16.154 -X-14.967Y16.248 -X-14.150Y16.448 -X-13.749Y16.554 -X-13.354Y16.664 -X-12.583Y16.895 -X-12.209Y17.017 -X-11.844Y17.142 -X-11.140Y17.405 -X-10.803Y17.542 -X-10.477Y17.683 -X-9.858Y17.975 -X-9.566Y18.127 -X-9.287Y18.283 -X-9.021Y18.442 -X-8.768Y18.604 -X-8.529Y18.771 -X-8.305Y18.940 -X-8.094Y19.113 -X-7.899Y19.290 -X-7.718Y19.470 -X-7.553Y19.653 -X-7.403Y19.839 -X-7.270Y20.029 -X-7.152Y20.221 -X-7.050Y20.417 -X-6.965Y20.616 -X-6.895Y20.818 -X-6.843Y21.023 -X-6.806Y21.230 -X-6.787Y21.441 -X-6.783Y21.654 -X-6.796Y21.870 -X-6.826Y22.088 -X-6.872Y22.309 -X-6.933Y22.532 -X-7.011Y22.758 -X-7.104Y22.986 -X-7.213Y23.217 -X-7.338Y23.449 -X-7.477Y23.684 -X-7.631Y23.921 -X-7.982Y24.401 -X-8.165Y24.627 -X-8.360Y24.855 -X-8.782Y25.315 -X-9.751Y26.251 -X-10.017Y26.488 -X-10.291Y26.726 -X-10.863Y27.204 -X-12.089Y28.170 -X-12.409Y28.413 -X-12.734Y28.657 -X-13.395Y29.145 -X-14.749Y30.124 -X-17.457Y32.077 -X-17.785Y32.320 -X-18.108Y32.561 -X-18.740Y33.042 -X-19.930Y33.994 -X-20.210Y34.229 -X-20.481Y34.463 -X-20.997Y34.927 -X-21.240Y35.157 -X-21.474Y35.386 -X-21.910Y35.838 -X-22.111Y36.062 -X-22.302Y36.284 -X-22.480Y36.505 -X-22.646Y36.723 -X-22.800Y36.940 -X-22.941Y37.155 -X-23.069Y37.367 -X-23.183Y37.578 -X-23.285Y37.786 -X-23.373Y37.993 -X-23.447Y38.197 -X-23.507Y38.398 -X-23.553Y38.598 -X-23.585Y38.795 -X-23.602Y38.989 -X-23.606Y39.181 -X-23.593Y39.386 -X-23.563Y39.588 -X-23.516Y39.787 -X-23.452Y39.983 -X-23.372Y40.175 -X-23.274Y40.364 -X-23.160Y40.550 -X-23.029Y40.732 -X-22.882Y40.910 -X-22.719Y41.086 -X-22.539Y41.257 -X-22.344Y41.425 -X-22.134Y41.589 -X-21.908Y41.749 -X-21.668Y41.906 -X-21.413Y42.059 -X-21.144Y42.208 -X-20.862Y42.353 -X-20.566Y42.494 -X-20.257Y42.631 -X-19.937Y42.763 -X-19.604Y42.892 -X-18.906Y43.138 -X-18.542Y43.254 -X-18.168Y43.366 -X-17.785Y43.474 -X-17.394Y43.578 -X-16.995Y43.678 -X-16.589Y43.773 -X-15.758Y43.950 -X-15.335Y44.033 -X-14.908Y44.111 -X-14.476Y44.184 -X-14.042Y44.253 -X-13.606Y44.318 -X-13.168Y44.379 -X-12.289Y44.486 -X-11.851Y44.534 -X-11.414Y44.576 -X-10.978Y44.615 -X-10.546Y44.649 -X-10.116Y44.679 -X-9.691Y44.704 -X-9.271Y44.726 -X-8.856Y44.742 -X-8.447Y44.755 -X-8.044Y44.763 -X-7.650Y44.767 -X-7.263Y44.766 -X-6.885Y44.762 -X-6.516Y44.753 -X-6.157Y44.740 -X-5.808Y44.723 -X-5.471Y44.702 -X-5.145Y44.676 -X-4.830Y44.647 -X-4.529Y44.613 -X-4.240Y44.576 -X-3.965Y44.535 -X-3.703Y44.489 -X-3.456Y44.440 -X-3.227Y44.388 -X-3.013Y44.332 -X-2.813Y44.273 -X-2.629Y44.210 -X-2.459Y44.144 -X-2.305Y44.074 -X-2.167Y44.001 -X-2.044Y43.925 -X-1.938Y43.845 -X-1.847Y43.762 -X-1.773Y43.675 -X-1.715Y43.586 -X-1.673Y43.494 -X-1.647Y43.398 -X-1.638Y43.299 -X-1.645Y43.198 -X-1.667Y43.094 -X-1.706Y42.987 -X-1.761Y42.877 -X-1.832Y42.765 -X-1.918Y42.650 -X-2.019Y42.532 -X-2.135Y42.412 -X-2.267Y42.290 -X-2.412Y42.166 -X-2.572Y42.039 -X-2.934Y41.779 -X-3.134Y41.646 -X-3.347Y41.511 -X-3.810Y41.235 -X-4.059Y41.095 -X-4.319Y40.953 -X-4.869Y40.664 -X-6.076Y40.071 -X-8.785Y38.840 -X-9.139Y38.683 -X-9.494Y38.526 -X-10.205Y38.212 -X-11.612Y37.583 -X-14.215Y36.343 -X-14.490Y36.201 -X-14.756Y36.061 -X-15.263Y35.782 -X-15.503Y35.645 -X-15.734Y35.508 -X-16.165Y35.239 -X-16.365Y35.106 -X-16.553Y34.975 -X-16.730Y34.845 -X-16.895Y34.717 -X-17.049Y34.590 -X-17.190Y34.465 -X-17.318Y34.341 -X-17.434Y34.219 -X-17.537Y34.099 -X-17.626Y33.981 -X-17.702Y33.865 -X-17.764Y33.751 -X-17.813Y33.639 -X-17.847Y33.528 -X-17.868Y33.420 -X-17.875Y33.315 -X-17.867Y33.211 -X-17.845Y33.110 -X-17.809Y33.011 -X-17.759Y32.914 -X-17.695Y32.820 -X-17.616Y32.728 -X-17.523Y32.639 -X-17.417Y32.552 -X-17.296Y32.468 -X-17.162Y32.387 -X-17.014Y32.308 -X-16.852Y32.232 -X-16.677Y32.159 -X-16.489Y32.089 -X-16.288Y32.021 -X-16.075Y31.956 -X-15.849Y31.895 -X-15.611Y31.836 -X-15.361Y31.780 -X-15.099Y31.727 -X-14.827Y31.677 -X-14.543Y31.631 -X-14.250Y31.587 -X-13.946Y31.547 -X-13.632Y31.509 -X-13.309Y31.475 -X-12.977Y31.444 -X-12.637Y31.417 -X-12.289Y31.392 -X-11.933Y31.371 -X-11.570Y31.353 -X-11.201Y31.338 -X-10.825Y31.327 -X-10.444Y31.319 -X-10.058Y31.314 -X-9.667Y31.313 -X-9.273Y31.315 -X-8.874Y31.320 -X-8.473Y31.329 -X-8.069Y31.341 -X-7.630Y31.358 -X-7.188Y31.379 -X-6.746Y31.404 -X-6.303Y31.433 -X-5.861Y31.466 -X-5.421Y31.503 -X-4.982Y31.544 -X-4.546Y31.589 -X-4.113Y31.638 -X-3.684Y31.691 -X-3.260Y31.748 -X-2.841Y31.809 -X-2.428Y31.873 -X-2.021Y31.942 -X-1.231Y32.091 -X-0.848Y32.171 -X-0.475Y32.255 -X-0.110Y32.343 -X0.243Y32.434 -X0.587Y32.530 -X0.919Y32.629 -X1.547Y32.838 -X1.842Y32.948 -X2.124Y33.061 -X2.392Y33.178 -X2.647Y33.299 -X2.887Y33.423 -X3.112Y33.550 -X3.323Y33.681 -X3.518Y33.815 -X3.698Y33.952 -X3.862Y34.092 -X4.010Y34.236 -X4.142Y34.383 -X4.257Y34.533 -X4.356Y34.685 -X4.439Y34.841 -X4.505Y35.000 -X4.554Y35.161 -X4.586Y35.325 -X4.602Y35.492 -X4.602Y35.662 -X4.584Y35.834 -X4.551Y36.008 -X4.501Y36.185 -X4.435Y36.364 -X4.353Y36.546 -X4.255Y36.730 -X4.142Y36.916 -X4.014Y37.104 -X3.871Y37.294 -X3.713Y37.486 -X3.356Y37.876 -X3.157Y38.073 -X2.944Y38.272 -X2.483Y38.675 -X1.425Y39.496 -X1.155Y39.690 -X0.877Y39.885 -X0.300Y40.277 -X-0.925Y41.070 -X-3.540Y42.667 -X-3.871Y42.867 -X-4.202Y43.066 -X-4.858Y43.463 -X-6.136Y44.252 -X-6.444Y44.447 -X-6.748Y44.642 -X-7.337Y45.028 -X-8.430Y45.788 -X-8.682Y45.975 -X-8.926Y46.161 -X-9.383Y46.527 -X-9.596Y46.708 -X-9.799Y46.887 -X-10.170Y47.241 -X-10.337Y47.415 -X-10.493Y47.587 -X-10.636Y47.757 -X-10.766Y47.925 -X-10.884Y48.091 -X-10.988Y48.255 -X-11.078Y48.416 -X-11.155Y48.576 -X-11.218Y48.733 -X-11.267Y48.888 -X-11.301Y49.040 -X-11.322Y49.190 -X-11.328Y49.337 -X-11.319Y49.482 -X-11.296Y49.624 -X-11.259Y49.763 -X-11.207Y49.900 -X-11.140Y50.033 -X-11.059Y50.164 -X-10.963Y50.293 -X-10.853Y50.418 -X-10.729Y50.540 -X-10.591Y50.659 -X-10.439Y50.775 -X-10.276Y50.886 -X-10.100Y50.994 -X-9.912Y51.098 -X-9.710Y51.200 -X-9.496Y51.298 -X-9.270Y51.394 -X-8.783Y51.574 -X-8.522Y51.660 -X-8.250Y51.742 -X-7.968Y51.821 -X-7.675Y51.897 -X-7.372Y51.969 -X-7.059Y52.038 -X-6.407Y52.165 -X-6.068Y52.223 -X-5.722Y52.278 -X-5.368Y52.330 -X-5.006Y52.378 -X-4.639Y52.422 -X-4.265Y52.463 -X-3.886Y52.500 -X-3.501Y52.533 -X-3.112Y52.563 -X-2.719Y52.590 -X-2.322Y52.613 -X-1.923Y52.632 -X-1.521Y52.647 -X-1.116Y52.659 -X-0.711Y52.667 -X-0.304Y52.672 -X0.103Y52.673 -X0.510Y52.670 -X0.916Y52.664 -X1.321Y52.654 -X1.724Y52.640 -X2.125Y52.623 -X2.524Y52.602 -X2.919Y52.577 -X3.310Y52.549 -X3.696Y52.517 -X4.078Y52.481 -X4.455Y52.442 -X4.826Y52.400 -X5.190Y52.354 -X5.548Y52.304 -X5.898Y52.251 -X6.241Y52.194 -X6.576Y52.134 -X6.902Y52.070 -X7.219Y52.003 -X7.526Y51.933 -X7.824Y51.859 -X8.389Y51.701 -X8.656Y51.617 -X8.911Y51.530 -X9.154Y51.439 -X9.386Y51.346 -X9.606Y51.249 -X9.814Y51.149 -X10.009Y51.046 -X10.191Y50.939 -X10.374Y50.821 -X10.541Y50.698 -X10.693Y50.573 -X10.829Y50.444 -X10.948Y50.311 -X11.052Y50.175 -X11.139Y50.036 -X11.209Y49.894 -X11.263Y49.748 -X11.301Y49.600 -X11.323Y49.448 -X11.327Y49.293 -X11.316Y49.136 -X11.288Y48.975 -X11.245Y48.812 -X11.185Y48.646 -X11.109Y48.478 -X11.018Y48.307 -X10.912Y48.133 -X10.790Y47.957 -X10.654Y47.779 -X10.503Y47.598 -X10.159Y47.230 -X9.967Y47.043 -X9.762Y46.854 -X9.314Y46.470 -X8.282Y45.681 -X7.999Y45.480 -X7.707Y45.278 -X7.098Y44.870 -X5.798Y44.041 -X3.014Y42.350 -X2.662Y42.138 -X2.311Y41.925 -X1.617Y41.500 -X0.273Y40.654 -X-0.049Y40.444 -X-0.365Y40.234 -X-0.975Y39.817 -X-2.088Y38.994 -X-2.324Y38.805 -X-2.551Y38.617 -X-2.974Y38.245 -X-3.170Y38.061 -X-3.354Y37.878 -X-3.687Y37.516 -X-3.836Y37.338 -X-3.972Y37.162 -X-4.096Y36.987 -X-4.206Y36.813 -X-4.304Y36.642 -X-4.388Y36.473 -X-4.459Y36.305 -X-4.515Y36.139 -X-4.558Y35.976 -X-4.587Y35.815 -X-4.602Y35.655 -X-4.603Y35.498 -X-4.589Y35.343 -X-4.561Y35.191 -X-4.519Y35.041 -X-4.462Y34.893 -X-4.391Y34.748 -X-4.306Y34.605 -X-4.207Y34.465 -X-4.094Y34.327 -X-3.967Y34.192 -X-3.826Y34.060 -X-3.671Y33.930 -X-3.503Y33.803 -X-3.321Y33.679 -X-3.126Y33.558 -X-2.919Y33.440 -X-2.698Y33.324 -X-2.466Y33.212 -X-2.221Y33.102 -X-1.697Y32.893 -X-1.418Y32.792 -X-1.128Y32.695 -X-0.828Y32.601 -X-0.518Y32.510 -X-0.198Y32.422 -X0.131Y32.338 -X0.814Y32.178 -X1.168Y32.104 -X1.529Y32.032 -X1.897Y31.964 -X2.271Y31.899 -X2.651Y31.838 -X3.037Y31.780 -X3.822Y31.674 -X4.221Y31.626 -X4.622Y31.581 -X5.027Y31.540 -X5.434Y31.502 -X5.842Y31.468 -X6.252Y31.437 -X6.662Y31.410 -X7.072Y31.386 -X7.515Y31.363 -X7.957Y31.345 -X8.398Y31.331 -X8.835Y31.321 -X9.269Y31.315 -X9.699Y31.313 -X10.123Y31.315 -X10.543Y31.321 -X10.956Y31.330 -X11.362Y31.344 -X11.761Y31.362 -X12.152Y31.383 -X12.534Y31.409 -X12.907Y31.438 -X13.269Y31.471 -X13.622Y31.508 -X13.963Y31.549 -X14.293Y31.593 -X14.611Y31.641 -X14.916Y31.693 -X15.209Y31.749 -X15.487Y31.808 -X15.753Y31.870 -X16.003Y31.936 -X16.240Y32.006 -X16.461Y32.079 -X16.667Y32.155 -X16.858Y32.235 -X17.033Y32.318 -X17.191Y32.404 -X17.334Y32.493 -X17.460Y32.586 -X17.570Y32.681 -X17.662Y32.780 -X17.739Y32.881 -X17.798Y32.986 -X17.840Y33.093 -X17.866Y33.203 -X17.875Y33.316 -X17.867Y33.431 -X17.842Y33.549 -X17.801Y33.670 -X17.743Y33.793 -X17.669Y33.918 -X17.579Y34.045 -X17.473Y34.175 -X17.352Y34.307 -X17.215Y34.441 -X17.063Y34.577 -X16.897Y34.715 -X16.522Y34.997 -X16.314Y35.140 -X16.093Y35.285 -X15.614Y35.580 -X15.357Y35.729 -X15.089Y35.879 -X14.522Y36.184 -X13.280Y36.806 -X12.957Y36.960 -X12.628Y37.115 -X11.954Y37.427 -X10.561Y38.054 -X7.746Y39.303 -X7.404Y39.457 -X7.067Y39.611 -X6.409Y39.915 -X5.172Y40.511 -X4.883Y40.657 -X4.603Y40.802 -X4.074Y41.087 -X3.825Y41.227 -X3.588Y41.365 -X3.148Y41.636 -X2.947Y41.769 -X2.760Y41.900 -X2.585Y42.029 -X2.425Y42.156 -X2.278Y42.280 -X2.146Y42.402 -X2.028Y42.522 -X1.926Y42.639 -X1.839Y42.754 -X1.767Y42.866 -X1.711Y42.976 -X1.671Y43.083 -X1.646Y43.187 -X1.638Y43.289 -X1.645Y43.387 -X1.669Y43.483 -X1.709Y43.576 -X1.765Y43.665 -X1.838Y43.752 -X1.926Y43.835 -X2.030Y43.915 -X2.150Y43.992 -X2.286Y44.065 -X2.438Y44.135 -X2.605Y44.202 -X2.787Y44.265 -X2.984Y44.324 -X3.195Y44.380 -X3.421Y44.433 -X3.661Y44.481 -X3.915Y44.526 -X4.182Y44.568 -X4.443Y44.603 -X4.714Y44.635 -X4.996Y44.663 -X5.289Y44.688 -X5.591Y44.710 -X5.902Y44.728 -X6.223Y44.743 -X6.552Y44.754 -X6.890Y44.762 -X7.235Y44.766 -X7.587Y44.767 -X7.946Y44.764 -X8.311Y44.758 -X8.683Y44.748 -X9.059Y44.735 -X9.440Y44.717 -X9.826Y44.697 -X10.216Y44.672 -X10.608Y44.644 -X11.004Y44.613 -X11.401Y44.578 -X11.800Y44.539 -X12.602Y44.450 -X13.003Y44.400 -X13.403Y44.347 -X13.803Y44.289 -X14.201Y44.229 -X14.596Y44.164 -X14.990Y44.096 -X15.766Y43.949 -X16.148Y43.870 -X16.525Y43.787 -X17.263Y43.611 -X17.623Y43.518 -X17.976Y43.421 -X18.661Y43.217 -X18.991Y43.109 -X19.313Y42.999 -X19.626Y42.884 -X19.929Y42.767 -X20.223Y42.645 -X20.506Y42.521 -X21.041Y42.262 -X21.292Y42.127 -X21.531Y41.990 -X21.758Y41.849 -X21.974Y41.704 -X22.176Y41.557 -X22.366Y41.407 -X22.544Y41.253 -X22.708Y41.097 -X22.859Y40.937 -X22.996Y40.775 -X23.119Y40.609 -X23.229Y40.441 -X23.325Y40.269 -X23.407Y40.095 -X23.475Y39.919 -X23.529Y39.739 -X23.571Y39.541 -X23.597Y39.341 -X23.606Y39.137 -X23.599Y38.930 -X23.575Y38.721 -X23.534Y38.508 -X23.477Y38.293 -X23.404Y38.075 -X23.315Y37.855 -X23.211Y37.632 -X23.091Y37.406 -X22.955Y37.178 -X22.805Y36.948 -X22.640Y36.716 -X22.268Y36.244 -X22.061Y36.005 -X21.841Y35.765 -X21.364Y35.278 -X20.274Y34.284 -X19.975Y34.031 -X19.668Y33.778 -X19.029Y33.267 -X17.670Y32.234 -X17.316Y31.974 -X16.959Y31.713 -X16.236Y31.190 -X14.771Y30.140 -X14.405Y29.877 -X14.040Y29.614 -X13.319Y29.089 -X11.923Y28.043 -X11.588Y27.783 -X11.260Y27.524 -X10.626Y27.008 -X10.322Y26.752 -X10.027Y26.497 -X9.467Y25.990 -X9.203Y25.738 -X8.951Y25.488 -X8.482Y24.992 -X8.266Y24.747 -X8.064Y24.503 -X7.700Y24.021 -X7.550Y23.799 -X7.412Y23.578 -X7.288Y23.359 -X7.177Y23.143 -X7.079Y22.928 -X6.995Y22.715 -X6.925Y22.504 -X6.868Y22.295 -X6.826Y22.089 -X6.798Y21.884 -X6.784Y21.682 -X6.785Y21.483 -X6.800Y21.285 -X6.829Y21.091 -X6.873Y20.898 -X6.931Y20.708 -X7.003Y20.521 -X7.090Y20.336 -X7.191Y20.154 -X7.306Y19.975 -X7.434Y19.799 -X7.577Y19.625 -X7.733Y19.454 -X7.903Y19.286 -X8.085Y19.121 -X8.281Y18.959 -X8.489Y18.800 -X8.710Y18.644 -X8.943Y18.491 -X9.188Y18.341 -X9.711Y18.051 -X9.989Y17.910 -X10.278Y17.773 -X10.884Y17.508 -X11.201Y17.381 -X11.527Y17.257 -X12.203Y17.019 -X12.552Y16.905 -X12.908Y16.795 -X13.639Y16.584 -X14.012Y16.484 -X14.390Y16.387 -X15.159Y16.204 -X15.548Y16.118 -X15.940Y16.035 -X16.729Y15.880 -X17.126Y15.808 -X17.522Y15.739 -X18.315Y15.612 -X18.709Y15.554 -X19.102Y15.499 -X19.492Y15.448 -X19.879Y15.401 -X20.263Y15.357 -X20.642Y15.316 -X21.017Y15.279 -X21.387Y15.245 -X21.744Y15.215 -X22.095Y15.189 -X22.440Y15.166 -X22.778Y15.146 -X23.109Y15.129 -X23.431Y15.116 -X23.746Y15.106 -X24.052Y15.099 -X24.349Y15.095 -X24.636Y15.095 -X24.914Y15.097 -X25.181Y15.103 -X25.438Y15.112 -X25.684Y15.123 -X25.919Y15.138 -X26.142Y15.156 -X26.354Y15.177 -X26.553Y15.200 -X26.740Y15.227 -X26.914Y15.256 -X27.076Y15.288 -X27.225Y15.323 -X27.360Y15.361 -X27.482Y15.402 -X27.591Y15.445 -X27.686Y15.491 -X27.767Y15.539 -X27.835Y15.590 -X27.888Y15.643 -X27.928Y15.699 -X27.954Y15.757 -X27.965Y15.818 -X27.963Y15.881 -X27.947Y15.946 -X27.917Y16.014 -X27.873Y16.083 -X27.816Y16.155 -X27.744Y16.229 -X27.660Y16.305 -X27.562Y16.382 -X27.451Y16.462 -X27.327Y16.544 -X27.042Y16.712 -X26.881Y16.799 -X26.707Y16.887 -X26.326Y17.069 -X26.118Y17.162 -X25.900Y17.256 -X25.433Y17.449 -X24.385Y17.849 -X21.934Y18.690 -X21.575Y18.807 -X21.212Y18.925 -X20.474Y19.161 -X18.977Y19.635 -X16.040Y20.572 -X15.691Y20.686 -X15.348Y20.800 -X14.684Y21.024 -X13.458Y21.457 -X13.176Y21.562 -X12.904Y21.666 -X12.396Y21.868 -X12.159Y21.966 -X11.936Y22.063 -X11.528Y22.250 -X11.345Y22.340 -X11.176Y22.429 -X11.022Y22.515 -X10.882Y22.599 -X10.757Y22.681 -X10.648Y22.760 -X10.554Y22.836 -X10.476Y22.910 -X10.413Y22.982 -X10.367Y23.051 -X10.337Y23.117 -X10.323Y23.180 -X10.325Y23.240 -X10.344Y23.298 -X10.379Y23.352 -X10.430Y23.403 -X10.497Y23.452 -X10.580Y23.497 -X10.680Y23.538 -X10.795Y23.577 -X10.926Y23.612 -X11.072Y23.644 -X11.233Y23.673 -X11.410Y23.698 -X11.601Y23.719 -X11.807Y23.737 -X12.027Y23.751 -X12.260Y23.762 -X12.507Y23.769 -X12.767Y23.772 -X13.040Y23.771 -X13.325Y23.767 -X13.601Y23.760 -X13.887Y23.749 -X14.182Y23.734 -X14.486Y23.717 -X14.799Y23.696 -X15.120Y23.671 -X15.448Y23.643 -X15.784Y23.612 -X16.126Y23.577 -X16.475Y23.538 -X16.829Y23.496 -X17.188Y23.450 -X17.552Y23.401 -X17.921Y23.348 -X18.667Y23.232 -X19.045Y23.169 -X19.424Y23.102 -X20.187Y22.957 -X20.569Y22.879 -X20.951Y22.797 -X21.712Y22.623 -X22.090Y22.531 -X22.466Y22.435 -X23.208Y22.232 -X23.574Y22.125 -X23.935Y22.015 -X24.641Y21.784 -X24.985Y21.663 -X25.323Y21.538 -X25.977Y21.279 -X26.292Y21.144 -X26.599Y21.006 -X27.186Y20.719 -X27.465Y20.571 -X27.734Y20.419 -X27.993Y20.264 -X28.241Y20.106 -X28.477Y19.944 -X28.702Y19.779 -X29.116Y19.440 -X29.305Y19.266 -X29.481Y19.088 -X29.644Y18.908 -X29.794Y18.724 -X29.930Y18.538 -X30.053Y18.349 -X30.162Y18.156 -X30.258Y17.961 -X30.339Y17.763 -X30.406Y17.563 -X30.459Y17.359 -X30.498Y17.153 -X30.522Y16.944 -X30.532Y16.733 -X30.528Y16.519 -X30.510Y16.303 -X30.474Y16.066 -X30.421Y15.826 -X30.352Y15.583 -X30.266Y15.337 -X30.164Y15.089 -X30.046Y14.839 -X29.912Y14.586 -X29.762Y14.330 -X29.597Y14.073 -X29.417Y13.813 -X29.014Y13.287 -X28.791Y13.021 -X28.555Y12.753 -X28.044Y12.211 -X27.769Y11.938 -X27.483Y11.663 -X26.879Y11.109 -X25.553Y9.985 -X22.573Y7.693 -X22.183Y7.405 -X21.791Y7.116 -X21.005Y6.537 -X19.442Y5.382 -X19.058Y5.094 -X18.678Y4.806 -X17.931Y4.232 -X16.513Y3.095 -X16.178Y2.813 -X15.852Y2.532 -X15.229Y1.974 -X14.933Y1.697 -X14.649Y1.422 -X14.115Y0.876 -X13.867Y0.606 -X13.632Y0.337 -X13.411Y0.071 -X13.204Y-0.194 -X13.010Y-0.457 -X12.832Y-0.717 -X12.668Y-0.976 -X12.520Y-1.232 -X12.395Y-1.469 -X12.284Y-1.703 -X12.188Y-1.936 -X12.105Y-2.167 -X12.036Y-2.395 -X11.982Y-2.621 -X11.942Y-2.844 -X11.916Y-3.065 -X11.905Y-3.284 -X11.908Y-3.500 -X11.926Y-3.713 -X11.959Y-3.924 -X12.005Y-4.132 -X12.067Y-4.338 -X12.142Y-4.540 -X12.232Y-4.740 -X12.336Y-4.937 -X12.453Y-5.131 -X12.584Y-5.322 -X12.729Y-5.510 -X12.887Y-5.695 -X13.059Y-5.877 -X13.243Y-6.055 -X13.439Y-6.231 -X13.648Y-6.403 -X13.869Y-6.572 -X14.101Y-6.738 -X14.345Y-6.901 -X14.599Y-7.060 -X14.864Y-7.216 -X15.423Y-7.518 -X15.717Y-7.664 -X16.020Y-7.806 -X16.650Y-8.080 -X16.976Y-8.212 -X17.309Y-8.340 -X17.994Y-8.586 -X18.344Y-8.704 -X18.700Y-8.818 -X19.423Y-9.035 -X20.902Y-9.426 -X21.276Y-9.515 -X21.650Y-9.600 -X22.396Y-9.759 -X22.767Y-9.833 -X23.137Y-9.903 -X23.868Y-10.033 -X24.228Y-10.092 -X24.584Y-10.148 -X24.936Y-10.200 -X25.282Y-10.249 -X25.622Y-10.294 -X25.956Y-10.336 -X26.604Y-10.408 -X26.910Y-10.438 -X27.208Y-10.465 -X27.498Y-10.489 -X27.779Y-10.509 -X28.051Y-10.527 -X28.313Y-10.540 -X28.565Y-10.551 -X28.807Y-10.558 -X29.038Y-10.562 -X29.258Y-10.563 -X29.466Y-10.561 -X29.663Y-10.556 -X29.848Y-10.547 -X30.020Y-10.536 -X30.180Y-10.522 -X30.327Y-10.504 -X30.462Y-10.484 -X30.583Y-10.461 -X30.690Y-10.435 -X30.784Y-10.406 -X30.865Y-10.374 -X30.932Y-10.340 -X30.984Y-10.303 -X31.023Y-10.263 -X31.048Y-10.221 -X31.058Y-10.176 -X31.055Y-10.128 -X31.037Y-10.078 -X31.006Y-10.026 -X30.960Y-9.971 -X30.900Y-9.914 -X30.827Y-9.855 -X30.739Y-9.794 -X30.638Y-9.730 -X30.524Y-9.664 -X30.396Y-9.596 -X30.255Y-9.527 -X30.100Y-9.455 -X29.754Y-9.306 -X29.562Y-9.228 -X29.359Y-9.149 -X28.917Y-8.986 -X27.902Y-8.642 -X27.624Y-8.553 -X27.336Y-8.462 -X26.734Y-8.278 -X25.440Y-7.896 -X22.592Y-7.100 -X22.191Y-6.990 -X21.787Y-6.879 -X20.978Y-6.659 -X19.371Y-6.218 -X18.976Y-6.109 -X18.584Y-6.000 -X17.814Y-5.783 -X16.349Y-5.360 -X16.002Y-5.257 -X15.664Y-5.155 -X15.016Y-4.954 -X14.708Y-4.856 -X14.410Y-4.759 -X13.850Y-4.569 -X13.589Y-4.477 -X13.340Y-4.387 -X12.883Y-4.212 -X12.675Y-4.127 -X12.482Y-4.045 -X12.140Y-3.886 -X11.991Y-3.810 -X11.859Y-3.737 -X11.741Y-3.665 -X11.640Y-3.597 -X11.555Y-3.531 -X11.486Y-3.467 -X11.433Y-3.406 -X11.397Y-3.348 -X11.377Y-3.293 -X11.373Y-3.241 -X11.386Y-3.191 -X11.415Y-3.145 -X11.460Y-3.101 -X11.522Y-3.061 -X11.600Y-3.024 -X11.694Y-2.990 -X11.803Y-2.959 -X11.928Y-2.932 -X12.068Y-2.908 -X12.223Y-2.887 -X12.393Y-2.870 -X12.578Y-2.856 -X12.776Y-2.846 -X12.989Y-2.840 -X13.214Y-2.837 -X13.453Y-2.838 -X13.704Y-2.842 -X13.967Y-2.850 -X14.242Y-2.862 -X14.527Y-2.878 -X14.824Y-2.897 -X15.130Y-2.921 -X15.425Y-2.946 -X15.727Y-2.975 -X16.037Y-3.007 -X16.353Y-3.042 -X16.676Y-3.081 -X17.005Y-3.124 -X17.678Y-3.219 -X18.021Y-3.272 -X18.368Y-3.329 -X19.071Y-3.452 -X19.426Y-3.519 -X19.783Y-3.590 -X20.499Y-3.742 -X20.857Y-3.823 -X21.214Y-3.908 -X21.925Y-4.088 -X22.277Y-4.183 -X22.626Y-4.282 -X23.314Y-4.491 -X23.652Y-4.600 -X23.984Y-4.713 -X24.632Y-4.949 -X24.947Y-5.073 -X25.254Y-5.199 -X25.846Y-5.463 -X26.129Y-5.600 -X26.404Y-5.740 -X26.669Y-5.884 -X26.925Y-6.031 -X27.170Y-6.181 -X27.405Y-6.334 -X27.842Y-6.650 -X28.043Y-6.813 -X28.232Y-6.979 -X28.409Y-7.149 -X28.573Y-7.321 -X28.725Y-7.496 -X28.863Y-7.674 -X28.989Y-7.855 -X29.101Y-8.039 -X29.199Y-8.226 -X29.283Y-8.416 -X29.353Y-8.609 -X29.409Y-8.804 -X29.451Y-9.002 -X29.479Y-9.203 -X29.492Y-9.406 -X29.491Y-9.612 -X29.475Y-9.820 -X29.445Y-10.031 -X29.401Y-10.244 -X29.342Y-10.459 -X29.269Y-10.677 -X29.181Y-10.897 -X29.080Y-11.119 -X28.964Y-11.344 -X28.823Y-11.589 -X28.666Y-11.837 -X28.493Y-12.087 -X28.305Y-12.340 -X28.102Y-12.594 -X27.883Y-12.851 -X27.403Y-13.370 -X27.142Y-13.632 -X26.868Y-13.897 -X26.281Y-14.430 -X24.969Y-15.514 -X24.615Y-15.788 -X24.252Y-16.064 -X23.501Y-16.617 -X21.917Y-17.734 -X18.570Y-19.985 -X18.148Y-20.266 -X17.729Y-20.547 -X16.897Y-21.108 -X15.285Y-22.222 -X14.896Y-22.498 -X14.515Y-22.774 -X13.775Y-23.321 -X12.409Y-24.400 -X12.095Y-24.666 -X11.792Y-24.930 -X11.223Y-25.453 -X10.958Y-25.712 -X10.707Y-25.968 -X10.246Y-26.475 -X10.038Y-26.725 -X9.845Y-26.973 -X9.667Y-27.218 -X9.505Y-27.461 -X9.359Y-27.702 -X9.229Y-27.940 -X9.115Y-28.175 -X9.017Y-28.407 -X8.938Y-28.632 -X8.874Y-28.855 -X8.827Y-29.074 -X8.796Y-29.291 -X8.781Y-29.505 -X8.782Y-29.716 -X8.799Y-29.923 -X8.833Y-30.128 -X8.882Y-30.329 -X8.947Y-30.527 -X9.028Y-30.722 -X9.125Y-30.914 -X9.236Y-31.102 -X9.363Y-31.286 -X9.505Y-31.467 -X9.661Y-31.645 -X9.832Y-31.819 -X10.016Y-31.989 -X10.214Y-32.155 -X10.425Y-32.318 -X10.649Y-32.477 -X10.885Y-32.633 -X11.393Y-32.932 -X11.664Y-33.076 -X11.945Y-33.215 -X12.536Y-33.483 -X12.846Y-33.611 -X13.163Y-33.735 -X13.821Y-33.971 -X14.160Y-34.082 -X14.504Y-34.190 -X15.209Y-34.393 -X15.568Y-34.488 -X15.930Y-34.579 -X16.661Y-34.748 -X17.029Y-34.827 -X17.397Y-34.901 -X17.766Y-34.971 -X18.134Y-35.037 -X18.501Y-35.099 -X18.865Y-35.157 -X19.585Y-35.260 -X19.940Y-35.305 -X20.290Y-35.346 -X20.634Y-35.383 -X20.973Y-35.416 -X21.305Y-35.444 -X21.630Y-35.469 -X21.947Y-35.490 -X22.256Y-35.506 -X22.556Y-35.519 -X22.847Y-35.527 -X23.128Y-35.532 -X23.398Y-35.532 -X23.657Y-35.529 -X23.904Y-35.522 -X24.140Y-35.511 -X24.363Y-35.496 -X24.559Y-35.479 -X24.745Y-35.459 -X24.918Y-35.435 -X25.079Y-35.408 -X25.228Y-35.378 -X25.364Y-35.345 -X25.487Y-35.309 -X25.597Y-35.269 -X25.694Y-35.227 -X25.777Y-35.182 -X25.847Y-35.133 -X25.902Y-35.082 -X25.944Y-35.028 -X25.972Y-34.972 -X25.986Y-34.912 -X25.986Y-34.850 -X25.971Y-34.785 -X25.942Y-34.717 -X25.899Y-34.647 -X25.842Y-34.575 -X25.771Y-34.499 -X25.685Y-34.422 -X25.586Y-34.342 -X25.472Y-34.260 -X25.345Y-34.175 -X25.204Y-34.088 -X24.883Y-33.909 -X24.702Y-33.815 -X24.509Y-33.720 -X24.085Y-33.525 -X23.855Y-33.424 -X23.613Y-33.321 -X23.095Y-33.112 -X21.933Y-32.673 -X19.198Y-31.738 -X12.952Y-29.747 -X12.533Y-29.612 -X12.117Y-29.477 -X11.302Y-29.208 -X9.752Y-28.680 -X9.384Y-28.550 -X9.026Y-28.422 -X8.340Y-28.168 -X7.104Y-27.677 -X6.826Y-27.559 -X6.561Y-27.442 -X6.073Y-27.213 -X5.850Y-27.102 -X5.643Y-26.992 -X5.272Y-26.780 -X5.111Y-26.677 -X4.965Y-26.577 -X4.835Y-26.479 -X4.721Y-26.383 -X4.623Y-26.290 -X4.542Y-26.199 -X4.478Y-26.112 -X4.430Y-26.026 -X4.398Y-25.944 -X4.384Y-25.865 -X4.385Y-25.788 -X4.403Y-25.714 -X4.438Y-25.644 -X4.489Y-25.576 -X4.556Y-25.512 -X4.639Y-25.450 -X4.738Y-25.392 -X4.852Y-25.337 -X4.981Y-25.286 -X5.126Y-25.238 -X5.285Y-25.193 -X5.458Y-25.152 -X5.646Y-25.115 -X5.847Y-25.080 -X6.061Y-25.050 -X6.287Y-25.023 -X6.527Y-25.000 -X6.777Y-24.980 -X7.040Y-24.964 -X7.313Y-24.952 -X7.596Y-24.944 -X7.889Y-24.939 -X8.191Y-24.939 -X8.502Y-24.942 -X8.820Y-24.949 -X9.146Y-24.960 -X9.478Y-24.975 -X9.817Y-24.994 -X10.161Y-25.017 -X10.510Y-25.044 -X10.839Y-25.072 -X11.171Y-25.104 -X11.506Y-25.140 -X11.842Y-25.179 -X12.180Y-25.221 -X12.519Y-25.267 -X13.196Y-25.370 -X13.534Y-25.427 -X13.870Y-25.487 -X14.204Y-25.550 -X14.535Y-25.617 -X14.864Y-25.688 -X15.188Y-25.762 -X15.824Y-25.920 -X16.134Y-26.004 -X16.438Y-26.092 -X16.736Y-26.183 -X17.027Y-26.277 -X17.311Y-26.375 -X17.587Y-26.476 -X18.113Y-26.689 -X18.362Y-26.800 -X18.602Y-26.914 -X18.832Y-27.032 -X19.052Y-27.152 -X19.260Y-27.276 -X19.457Y-27.403 -X19.643Y-27.534 -X19.817Y-27.667 -X19.979Y-27.803 -X20.128Y-27.943 -X20.264Y-28.085 -X20.387Y-28.230 -X20.497Y-28.379 -X20.594Y-28.530 -X20.676Y-28.684 -X20.745Y-28.840 -X20.800Y-29.000 -X20.841Y-29.162 -X20.867Y-29.327 -X20.879Y-29.494 -X20.876Y-29.664 -X20.859Y-29.837 -X20.828Y-30.012 -X20.781Y-30.189 -X20.721Y-30.369 -X20.645Y-30.551 -X20.556Y-30.735 -X20.452Y-30.922 -X20.333Y-31.110 -X20.201Y-31.301 -X20.055Y-31.494 -X19.894Y-31.688 -X19.721Y-31.885 -X19.533Y-32.084 -X19.120Y-32.486 -X18.893Y-32.690 -X18.655Y-32.896 -X18.142Y-33.311 -X17.874Y-33.517 -X17.595Y-33.724 -X17.007Y-34.142 -X15.720Y-34.991 -X12.798Y-36.727 -X12.410Y-36.947 -X12.018Y-37.167 -X11.225Y-37.607 -X9.621Y-38.487 -X6.455Y-40.236 -X6.074Y-40.452 -X5.697Y-40.668 -X4.960Y-41.096 -X3.566Y-41.941 -X3.237Y-42.149 -X2.916Y-42.356 -X2.302Y-42.766 -X1.194Y-43.568 -X0.944Y-43.764 -X0.706Y-43.959 -X0.264Y-44.342 -X0.062Y-44.531 -X-0.128Y-44.718 -X-0.469Y-45.085 -X-0.620Y-45.266 -X-0.758Y-45.444 -X-0.882Y-45.620 -X-0.993Y-45.794 -X-1.090Y-45.965 -X-1.173Y-46.134 -X-1.243Y-46.301 -X-1.298Y-46.465 -X-1.342Y-46.640 -X-1.371Y-46.812 -X-1.382Y-46.980 -X-1.378Y-47.146 -X-1.357Y-47.308 -X-1.320Y-47.467 -X-1.267Y-47.622 -X-1.198Y-47.775 -X-1.114Y-47.923 -X-1.014Y-48.068 -X-0.899Y-48.210 -X-0.769Y-48.348 -X-0.625Y-48.482 -X-0.466Y-48.612 -X-0.293Y-48.739 -X-0.107Y-48.862 -X0.093Y-48.981 -X0.305Y-49.097 -X0.530Y-49.208 -X0.766Y-49.315 -X1.014Y-49.419 -X1.273Y-49.518 -X1.822Y-49.705 -X2.110Y-49.792 -X2.407Y-49.875 -X2.713Y-49.954 -X3.026Y-50.029 -X3.346Y-50.100 -X3.672Y-50.166 -X4.004Y-50.229 -X4.341Y-50.287 -X4.683Y-50.340 -X5.028Y-50.390 -X5.376Y-50.435 -X5.727Y-50.476 -X6.080Y-50.513 -X6.433Y-50.545 -X6.787Y-50.573 -X7.141Y-50.597 -X7.494Y-50.617 -X7.845Y-50.632 -X8.194Y-50.643 -X8.540Y-50.650 -X8.882Y-50.652 -X9.220Y-50.651 -X9.553Y-50.645 -X9.881Y-50.635 -X10.202Y-50.620 -X10.516Y-50.602 -X10.823Y-50.579 -X11.122Y-50.552 -X11.412Y-50.521 -X11.693Y-50.486 -X11.964Y-50.447 -X12.225Y-50.404 -X12.475Y-50.356 -X12.714Y-50.305 -X12.941Y-50.250 -X13.155Y-50.191 -X13.357Y-50.128 -X13.546Y-50.061 -X13.721Y-49.990 -X13.882Y-49.916 -X14.020Y-49.843 -X14.144Y-49.767 -X14.256Y-49.688 -X14.355Y-49.605 -X14.441Y-49.520 -X14.513Y-49.431 -X14.571Y-49.340 -X14.615Y-49.245 -X14.645Y-49.148 -X14.662Y-49.048 -X14.664Y-48.944 -X14.651Y-48.838 -X14.625Y-48.730 -X14.584Y-48.618 -X14.529Y-48.504 -X14.459Y-48.387 -X14.376Y-48.268 -X14.278Y-48.146 -X14.166Y-48.022 -X14.040Y-47.896 -X13.900Y-47.767 -X13.747Y-47.635 -X13.399Y-47.366 -X13.206Y-47.228 -X12.999Y-47.088 -X12.548Y-46.803 -X11.504Y-46.209 -X11.215Y-46.057 -X10.916Y-45.902 -X10.287Y-45.589 -X8.923Y-44.948 -X5.870Y-43.614 -X5.468Y-43.444 -X5.063Y-43.274 -X4.246Y-42.931 -X2.603Y-42.244 -X-0.599Y-40.871 -X-1.025Y-40.682 -X-1.444Y-40.493 -X-2.257Y-40.118 -X-3.764Y-39.380 -X-4.113Y-39.199 -X-4.450Y-39.019 -X-5.084Y-38.665 -X-5.380Y-38.490 -X-5.662Y-38.317 -X-6.181Y-37.977 -X-6.417Y-37.810 -X-6.637Y-37.645 -X-6.841Y-37.483 -X-7.028Y-37.322 -X-7.199Y-37.165 -X-7.352Y-37.009 -X-7.488Y-36.856 -X-7.607Y-36.706 -X-7.708Y-36.559 -X-7.791Y-36.414 -X-7.856Y-36.272 -X-7.904Y-36.133 -X-7.934Y-35.997 -X-7.946Y-35.864 -X-7.941Y-35.734 -X-7.918Y-35.608 -X-7.877Y-35.484 -X-7.819Y-35.364 -X-7.744Y-35.247 -X-7.652Y-35.134 -X-7.543Y-35.024 -X-7.418Y-34.918 -X-7.277Y-34.815 -X-7.121Y-34.716 -X-6.949Y-34.620 -X-6.762Y-34.528 -X-6.560Y-34.440 -X-6.345Y-34.356 -X-6.116Y-34.276 -X-5.874Y-34.199 -X-5.620Y-34.127 -X-5.353Y-34.058 -X-5.076Y-33.993 -X-4.787Y-33.933 -X-4.489Y-33.876 -X-4.181Y-33.824 -X-3.864Y-33.775 -X-3.539Y-33.731 -X-3.207Y-33.691 -X-2.867Y-33.655 -X-2.522Y-33.623 -X-2.172Y-33.596 -X-1.817Y-33.572 -X-1.458Y-33.553 -X-1.096Y-33.538 -X-0.732Y-33.528 -X-0.366Y-33.521 -X0.000Y-33.519 -G0Z6.000 -G0X37.560Y12.327Z6.000 -G1Z-1.000 -G1Y0.876 -X49.011 -Y12.327 -X37.560 -G0Z6.000 -G0Y0.876 -G1Z-1.000 -G1Y-10.575 -X49.011 -Y0.876 -X37.560 -G0Z6.000 -G0X49.011Y12.327 -G1Z-1.000 -G1X52.084Y15.011 -G0Z6.000 -G0X49.011Y0.876 -G1Z-1.000 -G1X52.084Y6.213 -Y15.011 -X43.286 -X37.560Y12.327 -G0Z6.000 -G0X49.011Y-10.575 -G1Z-1.000 -G1X52.084Y-2.585 -Y6.213 -X49.011Y0.876 -G0Z6.000 -G0Z20.000 -G0X0.000Y0.000 -M30 diff --git a/test/settings/kikigey89.settings b/test/settings/kikigey89.settings deleted file mode 100644 index e367d50..0000000 --- a/test/settings/kikigey89.settings +++ /dev/null @@ -1,31 +0,0 @@ -(Machine settings provided by @kikigey89) -$0=87.489 (x, step/mm) -$1=87.489 (y, step/mm) -$2=1280.000 (z, step/mm) -$3=1000.000 (x max rate, mm/min) -$4=1000.000 (y max rate, mm/min) -$5=500.000 (z max rate, mm/min) -$6=10.000 (x accel, mm/sec^2) -$7=10.000 (y accel, mm/sec^2) -$8=10.000 (z accel, mm/sec^2) -$9=211.000 (x max travel, mm) -$10=335.000 (y max travel, mm) -$11=70.000 (z max travel, mm) -$12=20 (step pulse, usec) -$13=160 (step port invert mask:10100000) -$14=160 (dir port invert mask:10100000) -$15=50 (step idle delay, msec) -$16=0.010 (junction deviation, mm) -$17=0.002 (arc tolerance, mm) -$19=0 (report inches, bool) -$20=1 (auto start, bool) -$21=0 (invert step enable, bool) -$22=0 (invert limit pins, bool) -$23=0 (soft limits, bool) -$24=0 (hard limits, bool) -$25=0 (homing cycle, bool) -$26=0 (homing dir invert mask:00000000) -$27=50.000 (homing feed, mm/min) -$28=500.000 (homing seek, mm/min) -$29=10 (homing debounce, msec) -$30=3.000 (homing pull-off, mm) \ No newline at end of file diff --git a/test/test.py b/test/test.py deleted file mode 100644 index 41c845c..0000000 --- a/test/test.py +++ /dev/null @@ -1,25 +0,0 @@ -import random -import serial -import time -ser = serial.Serial('/dev/tty.usbmodem24111', 115200, timeout=0.001) -time.sleep(1) -outstanding = 0 -data = '' -while True: - time.sleep(0.1) - data += ser.read() - pos = data.find('\n') - if pos == -1: - line = '' - else: - line = data[0:pos + 1] - data = data[pos + 1:] - if line == '' and outstanding < 3: - while outstanding < 3: - ser.write("G0 Z%0.3f\n" % (0.01 * (random.random() - 0.5))) - #ser.write("M3\n") - outstanding += 1 - continue - if line == 'ok\r\n': - outstanding -= 1 - print outstanding, repr(line.rstrip()) \ No newline at end of file From bf37ab7e7be6b6f44a86bf03c223113f46facc7a Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Sat, 17 Jan 2015 08:12:37 -0700 Subject: [PATCH 18/40] Fully configurable pins for NO or NC switches. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - All pins, which include limits, control command, and probe pins, can now all be configured to trigger as active-low or active-high and whether the pin has its internal pull-up resistor enabled. This should allow for just about all types of NO and NC switch configurations. - The probe pin invert setting hasn’t been added to the Grbl settings, like the others, and will have to wait until v1.0. But for now, it’s available as a compile-time option in config.h. - Fixed a variable spindle bug. --- config.h | 21 ++++++++++++++++++++ cpu_map.h | 50 +++++++++++++++++++++++------------------------ defaults.h | 2 +- limits.c | 8 ++++---- main.c | 2 +- planner.c | 2 +- probe.c | 6 +++--- settings.h | 2 +- spindle_control.c | 2 +- system.c | 38 ++++++++++++++++++++++------------- 10 files changed, 82 insertions(+), 51 deletions(-) diff --git a/config.h b/config.h index 60d240b..9a55119 100644 --- a/config.h +++ b/config.h @@ -143,6 +143,11 @@ // have the same steps per mm internally. // #define COREXY // Default disabled. Uncomment to enable. +// Inverts pin logic of the control command pins. This essentially means when this option is enabled +// you can use normally-closed switches, rather than the default normally-open switches. +// NOTE: Will eventually be added to Grbl settings in v1.0. +// #define INVERT_CONTROL_PIN // Default disabled. Uncomment to enable. + // --------------------------------------------------------------------------------------- // ADVANCED CONFIGURATION OPTIONS: @@ -162,6 +167,22 @@ // step smoothing. See stepper.c for more details on the AMASS system works. #define ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING // Default enabled. Comment to disable. +// By default, Grbl sets all input pins to normal-high operation with their internal pull-up resistors +// enabled. This simplifies the wiring for users by requiring only a switch connected to ground, +// although its recommended that users take the extra step of wiring in low-pass filter to reduce +// electrical noise detected by the pin. If the user inverts the pin in Grbl settings, this just flips +// which high or low reading indicates an active signal. In normal operation, this means the user +// needs to connect a normal-open switch, but if inverted, this means the user should connect a +// normal-closed switch. +// The following options disable the internal pull-up resistors, sets the pins to a normal-low +// operation, and switches much be now connect to Vcc instead of ground. This also flips the meaning +// of the invert pin Grbl setting, where an inverted setting now means the user should connect a +// normal-open switch and vice versa. +// WARNING: When the pull-ups are disabled, this requires additional wiring with pull-down resistors! +//#define DISABLE_LIMIT_PIN_PULL_UP +//#define DISABLE_PROBE_PIN_PULL_UP +//#define DISABLE_CONTROL_PIN_PULL_UP + // Sets which axis the tool length offset is applied. Assumes the spindle is always parallel with // the selected axis with the tool oriented toward the negative direction. In other words, a positive // tool length offset value is subtracted from the current location. diff --git a/cpu_map.h b/cpu_map.h index 3e46c30..4bdb61a 100644 --- a/cpu_map.h +++ b/cpu_map.h @@ -60,7 +60,7 @@ #define STEPPERS_DISABLE_MASK (1< 0); // The active cycle axes should now be homed and machine limits have been located. By - // default, grbl defines machine space as all negative, as do most CNCs. Since limit switches + // default, Grbl defines machine space as all negative, as do most CNCs. Since limit switches // can be on either side of an axes, check and set axes machine zero appropriately. Also, // set up pull-off maneuver from axes limit switches that have been homed. This provides // some initial clearance off the switches and should also help prevent them from falsely diff --git a/main.c b/main.c index cd83478..bdda1e7 100644 --- a/main.c +++ b/main.c @@ -47,7 +47,7 @@ int main(void) { // Initialize system upon power-up. serial_init(); // Setup serial baud rate and interrupts - settings_init(); // Load grbl settings from EEPROM + settings_init(); // Load Grbl settings from EEPROM stepper_init(); // Configure stepper pins and interrupt timers system_init(); // Configure pinout pins and pin-change interrupt diff --git a/planner.c b/planner.c index cc41535..c0b1742 100644 --- a/planner.c +++ b/planner.c @@ -371,7 +371,7 @@ uint8_t plan_check_full_buffer() colinear with the circle center. The circular segment joining the two paths represents the path of centripetal acceleration. Solve for max velocity based on max acceleration about the radius of the circle, defined indirectly by junction deviation. This may be also viewed as - path width or max_jerk in the previous grbl version. This approach does not actually deviate + path width or max_jerk in the previous Grbl version. This approach does not actually deviate from path, but used as a robust way to compute cornering speeds, as it takes into account the nonlinearities of both the junction angle and junction velocity. diff --git a/probe.c b/probe.c index e7063b0..5d0224f 100644 --- a/probe.c +++ b/probe.c @@ -30,11 +30,11 @@ uint8_t probe_invert_mask; void probe_init() { PROBE_DDR &= ~(PROBE_MASK); // Configure as input pins - if (bit_istrue(settings.flags,BITFLAG_INVERT_PROBE_PIN)) { + #ifdef DISABLE_PROBE_PIN_PULL_UP PROBE_PORT &= ~(PROBE_MASK); // Normal low operation. Requires external pull-down. - } else { + #else PROBE_PORT |= PROBE_MASK; // Enable internal pull-up resistors. Normal high operation. - } + #endif // probe_configure_invert_mask(false); // Initialize invert mask. Not required. Updated when in-use. } diff --git a/settings.h b/settings.h index c201ad7..426ea40 100644 --- a/settings.h +++ b/settings.h @@ -29,7 +29,7 @@ #define GRBL_VERSION "0.9h" -#define GRBL_VERSION_BUILD "20150114" +#define GRBL_VERSION_BUILD "20150117" // Version of the EEPROM data. Will be used to migrate existing data from older versions of Grbl // when firmware is upgraded. Always stored in byte 0 of eeprom diff --git a/spindle_control.c b/spindle_control.c index 84b8612..b928ada 100644 --- a/spindle_control.c +++ b/spindle_control.c @@ -113,7 +113,7 @@ void spindle_set_state(uint8_t state, float rpm) void spindle_run(uint8_t state, float rpm) { - if (sys.state != STATE_CHECK_MODE) { return; } + if (sys.state == STATE_CHECK_MODE) { return; } protocol_buffer_synchronize(); // Empty planner buffer to ensure spindle is set when programmed. spindle_set_state(state, rpm); } diff --git a/system.c b/system.c index 046b72b..9c42845 100644 --- a/system.c +++ b/system.c @@ -30,10 +30,14 @@ void system_init() { - PINOUT_DDR &= ~(PINOUT_MASK); // Configure as input pins - PINOUT_PORT |= PINOUT_MASK; // Enable internal pull-up resistors. Normal high operation. - PINOUT_PCMSK |= PINOUT_MASK; // Enable specific pins of the Pin Change Interrupt - PCICR |= (1 << PINOUT_INT); // Enable Pin Change Interrupt + CONTROL_DDR &= ~(CONTROL_MASK); // Configure as input pins + #ifdef DISABLE_CONTROL_PIN_PULL_UP + CONTROL_PORT &= ~(CONTROL_MASK); // Normal low operation. Requires external pull-down. + #else + CONTROL_PORT |= CONTROL_MASK; // Enable internal pull-up resistors. Normal high operation. + #endif + CONTROL_PCMSK |= CONTROL_MASK; // Enable specific pins of the Pin Change Interrupt + PCICR |= (1 << CONTROL_INT); // Enable Pin Change Interrupt } @@ -41,15 +45,19 @@ void system_init() // only the realtime command execute variable to have the main program execute these when // its ready. This works exactly like the character-based realtime commands when picked off // directly from the incoming serial data stream. -ISR(PINOUT_INT_vect) +ISR(CONTROL_INT_vect) { - // Enter only if any pinout pin is actively low. - if ((PINOUT_PIN & PINOUT_MASK) ^ PINOUT_MASK) { - if (bit_isfalse(PINOUT_PIN,bit(PIN_RESET))) { + uint8_t pin = (CONTROL_PIN & CONTROL_MASK); + #ifndef INVERT_CONTROL_PIN + pin ^= CONTROL_MASK; + #endif + // Enter only if any CONTROL pin is detected as active. + if (pin) { + if (bit_istrue(pin,bit(RESET_BIT))) { mc_reset(); - } else if (bit_isfalse(PINOUT_PIN,bit(PIN_FEED_HOLD))) { + } else if (bit_istrue(pin,bit(FEED_HOLD_BIT))) { bit_true(sys.rt_exec_state, EXEC_FEED_HOLD); - } else if (bit_isfalse(PINOUT_PIN,bit(PIN_CYCLE_START))) { + } else if (bit_istrue(pin,bit(CYCLE_START_BIT))) { bit_true(sys.rt_exec_state, EXEC_CYCLE_START); } } @@ -208,15 +216,17 @@ uint8_t system_execute_line(char *line) float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx) { + float pos; #ifdef COREXY if (idx==A_MOTOR) { - return((0.5*(steps[A_MOTOR] + steps[B_MOTOR]))/settings.steps_per_mm[idx]); - } else if (idx==B_MOTOR) { - return((0.5*(steps[A_MOTOR] - steps[B_MOTOR]))/settings.steps_per_mm[idx]); + pos = 0.5*((steps[A_MOTOR] + steps[B_MOTOR])/settings.steps_per_mm[idx]); + } else { // (idx==B_MOTOR) + pos = 0.5*((steps[A_MOTOR] - steps[B_MOTOR])/settings.steps_per_mm[idx]); } #else - return((float)steps[idx]/settings.steps_per_mm[idx]); + pos = steps[idx]/settings.steps_per_mm[idx]; #endif + return(pos); } From a358c6de0bbd55463d0914b2d23dfbfd12624b78 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Wed, 4 Feb 2015 19:12:30 -0700 Subject: [PATCH 19/40] Rare planner bug fix and added simulator defaults. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Planner bug when moving along a diagonal back and forth on the same path. Rare for the fact that most CAM programs don’t program this type of motion, neither does jogging. Fixed in this update. - Added grbl_sim defaults for testing purposes. --- defaults.h | 36 ++++++++++++++++++++++++++++++++++++ planner.c | 1 + settings.h | 2 +- system.c | 3 +++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/defaults.h b/defaults.h index 7f4bce1..06dc0f7 100644 --- a/defaults.h +++ b/defaults.h @@ -263,4 +263,40 @@ #define DEFAULT_HOMING_PULLOFF 1.0 // mm #endif +#ifdef DEFAULTS_SIMULATOR + // Settings only for Grbl Simulator (www.github.com/grbl/grbl-sim) + // Grbl generic default settings. Should work across different machines. + #define DEFAULT_X_STEPS_PER_MM 1000.0 + #define DEFAULT_Y_STEPS_PER_MM 1000.0 + #define DEFAULT_Z_STEPS_PER_MM 1000.0 + #define DEFAULT_X_MAX_RATE 1000.0 // mm/min + #define DEFAULT_Y_MAX_RATE 1000.0 // mm/min + #define DEFAULT_Z_MAX_RATE 1000.0 // mm/min + #define DEFAULT_X_ACCELERATION (100.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_Y_ACCELERATION (100.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_Z_ACCELERATION (100.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_X_MAX_TRAVEL 1000.0 // mm + #define DEFAULT_Y_MAX_TRAVEL 1000.0 // mm + #define DEFAULT_Z_MAX_TRAVEL 1000.0 // mm + #define DEFAULT_STEP_PULSE_MICROSECONDS 10 + #define DEFAULT_STEPPING_INVERT_MASK 0 + #define DEFAULT_DIRECTION_INVERT_MASK 0 + #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled) + #define DEFAULT_STATUS_REPORT_MASK ((BITFLAG_RT_STATUS_MACHINE_POSITION)|(BITFLAG_RT_STATUS_WORK_POSITION)) + #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm + #define DEFAULT_ARC_TOLERANCE 0.002 // mm + #define DEFAULT_REPORT_INCHES 0 // false + #define DEFAULT_AUTO_START 1 // true + #define DEFAULT_INVERT_ST_ENABLE 0 // false + #define DEFAULT_INVERT_LIMIT_PINS 0 // false + #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false + #define DEFAULT_HARD_LIMIT_ENABLE 0 // false + #define DEFAULT_HOMING_ENABLE 0 // false + #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir + #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min + #define DEFAULT_HOMING_SEEK_RATE 500.0 // mm/min + #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k) + #define DEFAULT_HOMING_PULLOFF 1.0 // mm +#endif + #endif diff --git a/planner.c b/planner.c index c0b1742..44ab051 100644 --- a/planner.c +++ b/planner.c @@ -388,6 +388,7 @@ uint8_t plan_check_full_buffer() change the overall maximum entry speed conditions of all blocks. */ // NOTE: Computed without any expensive trig, sin() or acos(), by trig half angle identity of cos(theta). + junction_cos_theta = min(junction_cos_theta, 1.0); // Check for numerical round-off. float sin_theta_d2 = sqrt(0.5*(1.0-junction_cos_theta)); // Trig half angle identity. Always positive. // TODO: Technically, the acceleration used in calculation needs to be limited by the minimum of the diff --git a/settings.h b/settings.h index 426ea40..df70906 100644 --- a/settings.h +++ b/settings.h @@ -29,7 +29,7 @@ #define GRBL_VERSION "0.9h" -#define GRBL_VERSION_BUILD "20150117" +#define GRBL_VERSION_BUILD "20150204" // Version of the EEPROM data. Will be used to migrate existing data from older versions of Grbl // when firmware is upgraded. Always stored in byte 0 of eeprom diff --git a/system.c b/system.c index 9c42845..12838ae 100644 --- a/system.c +++ b/system.c @@ -214,6 +214,9 @@ uint8_t system_execute_line(char *line) } +// Returns machine position of axis 'idx'. Must be sent a 'step' array. +// NOTE: If motor steps and machine position are not in the same coordinate frame, this function +// serves as a central place to compute the transformation. float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx) { float pos; From 23c1e154aae3232deb9bacafca293a8cc154c26e Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Fri, 6 Feb 2015 20:02:34 -0700 Subject: [PATCH 20/40] Limit/control pin state reporting option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - As a setup feature, users can compile-in input pin status reporting. Doesn’t do anything special, just prints the binary for the port. 0’s and 1’s indicate low and high signals on the pins. It’s a bit cryptic right now, but it’s just a start. - Added a max step rate check when writing step/mm and max rate settings. Should help avoid people misdiagnosing problems associated with going over the 30kHz step rate limit. Right now not enabled. Takes up over 100k of flash. Need that room for other things right now. --- config.h | 11 +++++++++++ report.c | 9 +++++++++ report.h | 1 + settings.c | 10 ++++++++-- 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/config.h b/config.h index 9a55119..601457e 100644 --- a/config.h +++ b/config.h @@ -148,6 +148,12 @@ // NOTE: Will eventually be added to Grbl settings in v1.0. // #define INVERT_CONTROL_PIN // Default disabled. Uncomment to enable. +// Enable input pin states feedback in status reports. The data is presented as a binary value with +// the bits in the appropriate input pin ports being 0(low) or 1(high). Useful for setting up a new +// CNC machine, but do not recommend keeping this option by default, as it will consume CPU resources +// with little to no benefit during normal operation. +// #define REPORT_INPUT_PIN_STATES // Default disabled. Uncomment to enable. + // --------------------------------------------------------------------------------------- // ADVANCED CONFIGURATION OPTIONS: @@ -167,6 +173,11 @@ // step smoothing. See stepper.c for more details on the AMASS system works. #define ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING // Default enabled. Comment to disable. +// Sets the maximum step rate allowed to be written as a Grbl setting. This value is strictly limited +// by the CPU speed and will change if something other than an AVR running at 16MHz is used. +// NOTE: For now disabled, will enable if flash space permits. +// #define MAX_STEP_RATE_HZ 30000 // Hz + // By default, Grbl sets all input pins to normal-high operation with their internal pull-up resistors // enabled. This simplifies the wiring for users by requiring only a switch connected to ground, // although its recommended that users take the extra step of wiring in low-pass filter to reduce diff --git a/report.c b/report.c index fd47e90..6e0d2da 100644 --- a/report.c +++ b/report.c @@ -75,6 +75,8 @@ void report_status_message(uint8_t status_code) printPgmString(PSTR("Homing not enabled")); break; case STATUS_OVERFLOW: printPgmString(PSTR("Line overflow")); break; + // case STATUS_MAX_STEP_RATE_EXCEEDED: + // printPgmString(PSTR("Step rate > 30kHz")); break; // Common g-code parser errors. case STATUS_GCODE_MODAL_GROUP_VIOLATION: @@ -449,5 +451,12 @@ void report_realtime_status() printFloat_RateValue(st_get_realtime_rate()); #endif + #ifdef REPORT_INPUT_PIN_STATES + printPgmString(PSTR(",Lim:")); + print_uint8_base2(LIMIT_PIN & LIMIT_MASK); + printPgmString(PSTR(",Ctl:")); + print_uint8_base2(CONTROL_PIN & CONTROL_MASK); + #endif + printPgmString(PSTR(">\r\n")); } diff --git a/report.h b/report.h index e770469..c0916aa 100644 --- a/report.h +++ b/report.h @@ -33,6 +33,7 @@ #define STATUS_ALARM_LOCK 9 #define STATUS_SOFT_LIMIT_ERROR 10 #define STATUS_OVERFLOW 11 +// #define STATUS_MAX_STEP_RATE_EXCEEDED 12 #define STATUS_GCODE_UNSUPPORTED_COMMAND 20 #define STATUS_GCODE_MODAL_GROUP_VIOLATION 21 diff --git a/settings.c b/settings.c index 56e2fab..a81e0e8 100644 --- a/settings.c +++ b/settings.c @@ -200,8 +200,14 @@ uint8_t settings_store_global_setting(uint8_t parameter, float value) { if (parameter < N_AXIS) { // Valid axis setting found. switch (set_idx) { - case 0: settings.steps_per_mm[parameter] = value; break; - case 1: settings.max_rate[parameter] = value; break; + case 0: + // if (value*settings.max_rate[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); } + settings.steps_per_mm[parameter] = value; + break; + case 1: + // if (value*settings.steps_per_mm[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); } + settings.max_rate[parameter] = value; + break; case 2: settings.acceleration[parameter] = value*60*60; break; // Convert to mm/min^2 for grbl internal use. case 3: settings.max_travel[parameter] = -value; break; // Store as negative for grbl internal use. } From 3b468f602b031a7f353fb7a5c986d829d1d14a52 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Tue, 10 Feb 2015 08:25:09 -0700 Subject: [PATCH 21/40] Bug fix for certain motions. Re-org of includes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Critical bug fix for diagonal motions that continue on the same direction or return in the exact opposite direction. This issue could cause Grbl to crash intermittently due to a numerical round-off error. Grbl versions prior to v0.9g shouldn’t have this issue. - Reorganized all of the includes used by Grbl. Centralized it into a single “grbl.h” include. This will help simplify the compiling and uploading process through the Arduino IDE. - Added an example .INO file for users to simply open and run when compiling and uploading through the IDE. More to come later. --- config.h | 1 - coolant_control.c | 5 +---- examples/Grbl/Grbl.ino | 22 ++++++++++++++++++++++ gcode.c | 10 +--------- grbl.h | 28 ++++++++++++++++++++++------ limits.c | 10 ++-------- main.c | 14 +------------- motion_control.c | 13 +------------ motion_control.h | 2 +- nuts_bolts.c | 3 +-- planner.c | 25 +++++++++++++------------ print.c | 4 +--- probe.c | 5 ++--- protocol.c | 10 +--------- report.c | 11 +---------- serial.c | 6 +----- settings.c | 8 +------- settings.h | 3 +-- spindle_control.c | 5 +---- stepper.c | 7 +------ system.c | 9 +-------- system.h | 20 +------------------- 22 files changed, 77 insertions(+), 144 deletions(-) create mode 100644 examples/Grbl/Grbl.ino diff --git a/config.h b/config.h index 601457e..0a0d886 100644 --- a/config.h +++ b/config.h @@ -32,7 +32,6 @@ #ifndef config_h #define config_h -#include "system.h" // Default settings. Used when resetting EEPROM. Change to desired name in defaults.h diff --git a/coolant_control.c b/coolant_control.c index d8336d5..f94f51a 100644 --- a/coolant_control.c +++ b/coolant_control.c @@ -18,10 +18,7 @@ along with Grbl. If not, see . */ -#include "system.h" -#include "coolant_control.h" -#include "protocol.h" -#include "gcode.h" +#include "grbl.h" void coolant_init() diff --git a/examples/Grbl/Grbl.ino b/examples/Grbl/Grbl.ino new file mode 100644 index 0000000..caf26fd --- /dev/null +++ b/examples/Grbl/Grbl.ino @@ -0,0 +1,22 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include diff --git a/gcode.c b/gcode.c index 69d58e0..ec5b44a 100644 --- a/gcode.c +++ b/gcode.c @@ -24,15 +24,7 @@ Copyright (c) 2011-2012 Sungeun K. Jeon */ -#include "system.h" -#include "settings.h" -#include "protocol.h" -#include "gcode.h" -#include "motion_control.h" -#include "spindle_control.h" -#include "coolant_control.h" -#include "probe.h" -#include "report.h" +#include "grbl.h" // NOTE: Max line number is defined by the g-code standard to be 99999. It seems to be an // arbitrary value, and some GUIs may require more. So we increased it based on a max safe diff --git a/grbl.h b/grbl.h index 913e4f5..6295e7c 100644 --- a/grbl.h +++ b/grbl.h @@ -25,25 +25,41 @@ #ifndef grbl_h #define grbl_h -// All of the Grbl system include files. +#define GRBL_VERSION "0.9h" +#define GRBL_VERSION_BUILD "20150210" + +// Define standard libraries used by Grbl. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Define the Grbl system include files. #include "config.h" -#include "coolant_control.h" -#include "cpu_map.h" +#include "nuts_bolts.h" +#include "settings.h" +#include "system.h" #include "defaults.h" +#include "cpu_map.h" +#include "coolant_control.h" #include "eeprom.h" #include "gcode.h" #include "limits.h" #include "motion_control.h" -#include "nuts_bolts.h" #include "planner.h" #include "print.h" #include "probe.h" #include "protocol.h" #include "report.h" #include "serial.h" -#include "settings.h" #include "spindle_control.h" #include "stepper.h" -#include "system.h" #endif diff --git a/limits.c b/limits.c index 0a5e391..a8a2583 100644 --- a/limits.c +++ b/limits.c @@ -24,14 +24,8 @@ Copyright (c) 2012 Sungeun K. Jeon */ -#include "system.h" -#include "settings.h" -#include "protocol.h" -#include "planner.h" -#include "stepper.h" -#include "motion_control.h" -#include "limits.h" -#include "report.h" +#include "grbl.h" + // Homing axis search distance multiplier. Computed by this value times the axis max travel. #define HOMING_AXIS_SEARCH_SCALAR 1.5 // Must be > 1 to ensure limit switch will be engaged. diff --git a/main.c b/main.c index bdda1e7..f3557c5 100644 --- a/main.c +++ b/main.c @@ -24,19 +24,7 @@ Copyright (c) 2011-2012 Sungeun K. Jeon */ -#include "system.h" -#include "serial.h" -#include "settings.h" -#include "protocol.h" -#include "gcode.h" -#include "planner.h" -#include "stepper.h" -#include "spindle_control.h" -#include "coolant_control.h" -#include "motion_control.h" -#include "limits.h" -#include "probe.h" -#include "report.h" +#include "grbl.h" // Declare system global variable structure diff --git a/motion_control.c b/motion_control.c index 1cd9d05..4a0fdb9 100644 --- a/motion_control.c +++ b/motion_control.c @@ -25,18 +25,7 @@ Copyright (c) 2011 Jens Geisler */ -#include "system.h" -#include "settings.h" -#include "protocol.h" -#include "gcode.h" -#include "planner.h" -#include "stepper.h" -#include "motion_control.h" -#include "spindle_control.h" -#include "coolant_control.h" -#include "limits.h" -#include "probe.h" -#include "report.h" +#include "grbl.h" // Execute linear motion in absolute millimeter coordinates. Feed rate given in millimeters/second diff --git a/motion_control.h b/motion_control.h index 285a928..1cd1b2e 100644 --- a/motion_control.h +++ b/motion_control.h @@ -26,7 +26,7 @@ #ifndef motion_control_h #define motion_control_h -#include "gcode.h" + #define HOMING_CYCLE_LINE_NUMBER -1 diff --git a/nuts_bolts.c b/nuts_bolts.c index d620a62..7da9d7e 100644 --- a/nuts_bolts.c +++ b/nuts_bolts.c @@ -24,8 +24,7 @@ Copyright (c) 2011-2012 Sungeun K. Jeon */ -#include "system.h" -#include "print.h" +#include "grbl.h" #define MAX_INT_DIGITS 8 // Maximum number of digits in int32 (and float) diff --git a/planner.c b/planner.c index 44ab051..0946ce1 100644 --- a/planner.c +++ b/planner.c @@ -25,12 +25,7 @@ Copyright (c) 2011 Jens Geisler */ -#include "system.h" -#include "planner.h" -#include "protocol.h" -#include "stepper.h" -#include "settings.h" - +#include "grbl.h" #define SOME_LARGE_VALUE 1.0E+38 // Used by rapids and acceleration maximization calculations. Just needs // to be larger than any feasible (mm/min)^2 or mm/sec^2 value. @@ -388,13 +383,19 @@ uint8_t plan_check_full_buffer() change the overall maximum entry speed conditions of all blocks. */ // NOTE: Computed without any expensive trig, sin() or acos(), by trig half angle identity of cos(theta). - junction_cos_theta = min(junction_cos_theta, 1.0); // Check for numerical round-off. - float sin_theta_d2 = sqrt(0.5*(1.0-junction_cos_theta)); // Trig half angle identity. Always positive. + if (junction_cos_theta > 0.99) { + // For a 0 degree acute junction, just set minimum junction speed. + block->max_junction_speed_sqr = MINIMUM_JUNCTION_SPEED*MINIMUM_JUNCTION_SPEED; + } else { + junction_cos_theta = max(junction_cos_theta,-0.99); // Check for numerical round-off to avoid divide by zero. + float sin_theta_d2 = sqrt(0.5*(1.0-junction_cos_theta)); // Trig half angle identity. Always positive. - // TODO: Technically, the acceleration used in calculation needs to be limited by the minimum of the - // two junctions. However, this shouldn't be a significant problem except in extreme circumstances. - block->max_junction_speed_sqr = max( MINIMUM_JUNCTION_SPEED*MINIMUM_JUNCTION_SPEED, - (block->acceleration * settings.junction_deviation * sin_theta_d2)/(1.0-sin_theta_d2) ); + // TODO: Technically, the acceleration used in calculation needs to be limited by the minimum of the + // two junctions. However, this shouldn't be a significant problem except in extreme circumstances. + block->max_junction_speed_sqr = max( MINIMUM_JUNCTION_SPEED*MINIMUM_JUNCTION_SPEED, + (block->acceleration * settings.junction_deviation * sin_theta_d2)/(1.0-sin_theta_d2) ); + + } } // Store block nominal speed diff --git a/print.c b/print.c index 65fb975..781cedc 100644 --- a/print.c +++ b/print.c @@ -24,9 +24,7 @@ Copyright (c) 2011-2012 Sungeun K. Jeon */ -#include "system.h" -#include "serial.h" -#include "settings.h" +#include "grbl.h" void printString(const char *s) diff --git a/probe.c b/probe.c index 5d0224f..74121e8 100644 --- a/probe.c +++ b/probe.c @@ -18,9 +18,8 @@ along with Grbl. If not, see . */ -#include "system.h" -#include "settings.h" -#include "probe.h" +#include "grbl.h" + // Inverts the probe pin state depending on user settings and probing cycle mode. uint8_t probe_invert_mask; diff --git a/protocol.c b/protocol.c index 1c2651a..239bb16 100644 --- a/protocol.c +++ b/protocol.c @@ -24,15 +24,7 @@ Copyright (c) 2011-2012 Sungeun K. Jeon */ -#include "system.h" -#include "serial.h" -#include "settings.h" -#include "protocol.h" -#include "gcode.h" -#include "planner.h" -#include "stepper.h" -#include "motion_control.h" -#include "report.h" +#include "grbl.h" static char line[LINE_BUFFER_SIZE]; // Line to be executed. Zero-terminated. diff --git a/report.c b/report.c index 6e0d2da..c611452 100644 --- a/report.c +++ b/report.c @@ -26,16 +26,7 @@ methods to accomodate their needs. */ -#include "system.h" -#include "report.h" -#include "print.h" -#include "settings.h" -#include "gcode.h" -#include "coolant_control.h" -#include "planner.h" -#include "spindle_control.h" -#include "stepper.h" -#include "serial.h" +#include "grbl.h" // Handles the primary confirmation protocol response for streaming interfaces and human-feedback. diff --git a/serial.c b/serial.c index 7b2339c..e4a63d2 100644 --- a/serial.c +++ b/serial.c @@ -24,11 +24,7 @@ Copyright (c) 2011-2012 Sungeun K. Jeon */ -#include -#include "system.h" -#include "serial.h" -#include "motion_control.h" -#include "protocol.h" +#include "grbl.h" uint8_t serial_rx_buffer[RX_BUFFER_SIZE]; diff --git a/settings.c b/settings.c index a81e0e8..d018fef 100644 --- a/settings.c +++ b/settings.c @@ -24,13 +24,7 @@ Copyright (c) 2011-2012 Sungeun K. Jeon */ -#include "system.h" -#include "settings.h" -#include "eeprom.h" -#include "protocol.h" -#include "report.h" -#include "limits.h" -#include "stepper.h" +#include "grbl.h" settings_t settings; diff --git a/settings.h b/settings.h index df70906..a86c0e9 100644 --- a/settings.h +++ b/settings.h @@ -27,9 +27,8 @@ #ifndef settings_h #define settings_h +#include "grbl.h" -#define GRBL_VERSION "0.9h" -#define GRBL_VERSION_BUILD "20150204" // Version of the EEPROM data. Will be used to migrate existing data from older versions of Grbl // when firmware is upgraded. Always stored in byte 0 of eeprom diff --git a/spindle_control.c b/spindle_control.c index b928ada..abad6c2 100644 --- a/spindle_control.c +++ b/spindle_control.c @@ -24,10 +24,7 @@ Copyright (c) 2012 Sungeun K. Jeon */ -#include "system.h" -#include "spindle_control.h" -#include "protocol.h" -#include "gcode.h" +#include "grbl.h" void spindle_init() diff --git a/stepper.c b/stepper.c index fbc0426..cd71aa0 100644 --- a/stepper.c +++ b/stepper.c @@ -24,12 +24,7 @@ Copyright (c) 2011-2012 Sungeun K. Jeon */ -#include "system.h" -#include "nuts_bolts.h" -#include "stepper.h" -#include "settings.h" -#include "planner.h" -#include "probe.h" +#include "grbl.h" // Some useful constants. diff --git a/system.c b/system.c index 12838ae..bec36d6 100644 --- a/system.c +++ b/system.c @@ -18,14 +18,7 @@ along with Grbl. If not, see . */ -#include "system.h" -#include "settings.h" -#include "protocol.h" -#include "gcode.h" -#include "motion_control.h" -#include "stepper.h" -#include "report.h" -#include "print.h" +#include "grbl.h" void system_init() diff --git a/system.h b/system.h index 94139be..2c2a89d 100644 --- a/system.h +++ b/system.h @@ -21,25 +21,7 @@ #ifndef system_h #define system_h -// Define system header files and standard libraries used by Grbl -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Define Grbl configuration and shared header files -#include "config.h" -#include "defaults.h" -#include "cpu_map.h" -#include "nuts_bolts.h" - +#include "grbl.h" // Define system executor bit map. Used internally by realtime protocol as realtime command flags, // which notifies the main program to execute the specified realtime command asynchronously. From b237ad566ad25a1503e14fa5f487c34f88bec01f Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Tue, 10 Feb 2015 19:30:40 -0700 Subject: [PATCH 22/40] File re-organization. New Makefile. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Re-organized source code files into a ‘grbl’ directory to lessen one step in compiling Grbl through the Arduino IDE. - Added an ‘examples’ directory with an upload .INO sketch to further simplify compiling and uploading Grbl via the Arduino IDE. - Updated the Makefile with regard to the source code no longer being in the root directory. All files generated by compiling is placed in a separate ‘build’ directory to keep things tidy. The makefile should operate in the same way as it did before. --- Makefile | 40 +++++++++++---------- README.md | 3 ++ examples/Grbl/Grbl.ino | 22 ------------ config.h => grbl/config.h | 5 +-- coolant_control.c => grbl/coolant_control.c | 0 coolant_control.h => grbl/coolant_control.h | 0 cpu_map.h => grbl/cpu_map.h | 0 defaults.h => grbl/defaults.h | 0 eeprom.c => grbl/eeprom.c | 0 eeprom.h => grbl/eeprom.h | 0 grbl/examples/grblUpload/grblUpload.ino | 29 +++++++++++++++ grbl/examples/grblUpload/license.txt | 21 +++++++++++ gcode.c => grbl/gcode.c | 0 gcode.h => grbl/gcode.h | 0 grbl.h => grbl/grbl.h | 9 ++--- limits.c => grbl/limits.c | 10 +++--- limits.h => grbl/limits.h | 0 main.c => grbl/main.c | 0 motion_control.c => grbl/motion_control.c | 0 motion_control.h => grbl/motion_control.h | 0 nuts_bolts.c => grbl/nuts_bolts.c | 0 nuts_bolts.h => grbl/nuts_bolts.h | 0 planner.c => grbl/planner.c | 0 planner.h => grbl/planner.h | 0 print.c => grbl/print.c | 0 print.h => grbl/print.h | 0 probe.c => grbl/probe.c | 0 probe.h => grbl/probe.h | 0 protocol.c => grbl/protocol.c | 0 protocol.h => grbl/protocol.h | 0 report.c => grbl/report.c | 0 report.h => grbl/report.h | 0 serial.c => grbl/serial.c | 0 serial.h => grbl/serial.h | 0 settings.c => grbl/settings.c | 0 settings.h => grbl/settings.h | 0 spindle_control.c => grbl/spindle_control.c | 0 spindle_control.h => grbl/spindle_control.h | 0 stepper.c => grbl/stepper.c | 0 stepper.h => grbl/stepper.h | 0 system.c => grbl/system.c | 0 system.h => grbl/system.h | 0 42 files changed, 86 insertions(+), 53 deletions(-) delete mode 100644 examples/Grbl/Grbl.ino rename config.h => grbl/config.h (98%) rename coolant_control.c => grbl/coolant_control.c (100%) rename coolant_control.h => grbl/coolant_control.h (100%) rename cpu_map.h => grbl/cpu_map.h (100%) rename defaults.h => grbl/defaults.h (100%) rename eeprom.c => grbl/eeprom.c (100%) rename eeprom.h => grbl/eeprom.h (100%) create mode 100644 grbl/examples/grblUpload/grblUpload.ino create mode 100644 grbl/examples/grblUpload/license.txt rename gcode.c => grbl/gcode.c (100%) rename gcode.h => grbl/gcode.h (100%) rename grbl.h => grbl/grbl.h (82%) rename limits.c => grbl/limits.c (99%) rename limits.h => grbl/limits.h (100%) rename main.c => grbl/main.c (100%) rename motion_control.c => grbl/motion_control.c (100%) rename motion_control.h => grbl/motion_control.h (100%) rename nuts_bolts.c => grbl/nuts_bolts.c (100%) rename nuts_bolts.h => grbl/nuts_bolts.h (100%) rename planner.c => grbl/planner.c (100%) rename planner.h => grbl/planner.h (100%) rename print.c => grbl/print.c (100%) rename print.h => grbl/print.h (100%) rename probe.c => grbl/probe.c (100%) rename probe.h => grbl/probe.h (100%) rename protocol.c => grbl/protocol.c (100%) rename protocol.h => grbl/protocol.h (100%) rename report.c => grbl/report.c (100%) rename report.h => grbl/report.h (100%) rename serial.c => grbl/serial.c (100%) rename serial.h => grbl/serial.h (100%) rename settings.c => grbl/settings.c (100%) rename settings.h => grbl/settings.h (100%) rename spindle_control.c => grbl/spindle_control.c (100%) rename spindle_control.h => grbl/spindle_control.h (100%) rename stepper.c => grbl/stepper.c (100%) rename stepper.h => grbl/stepper.h (100%) rename system.c => grbl/system.c (100%) rename system.h => grbl/system.h (100%) diff --git a/Makefile b/Makefile index 9bc5615..d825ee5 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # Part of Grbl # # Copyright (c) 2009-2011 Simen Svale Skogsrud -# Copyright (c) 2012 Sungeun K. Jeon +# Copyright (c) 2012-2015 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 @@ -31,9 +31,11 @@ DEVICE ?= atmega328p CLOCK = 16000000 PROGRAMMER ?= -c avrisp2 -P usb -OBJECTS = main.o motion_control.o gcode.o spindle_control.o coolant_control.o serial.o \ - protocol.o stepper.o eeprom.o settings.o planner.o nuts_bolts.o limits.o \ - print.o probe.o report.o system.o +SOURCE = main.c motion_control.c gcode.c spindle_control.c coolant_control.c serial.c \ + protocol.c stepper.c eeprom.c settings.c planner.c nuts_bolts.c limits.c \ + print.c probe.c report.c system.c +BUILDDIR = build +SOURCEDIR = grbl # FUSES = -U hfuse:w:0xd9:m -U lfuse:w:0x24:m FUSES = -U hfuse:w:0xd2:m -U lfuse:w:0xff:m @@ -42,22 +44,24 @@ FUSES = -U hfuse:w:0xd2:m -U lfuse:w:0xff:m AVRDUDE = avrdude $(PROGRAMMER) -p $(DEVICE) -B 10 -F COMPILE = avr-gcc -Wall -Os -DF_CPU=$(CLOCK) -mmcu=$(DEVICE) -I. -ffunction-sections +OBJECTS = $(addprefix $(BUILDDIR)/,$(notdir $(SOURCE:.c=.o))) + # symbolic targets: all: grbl.hex -.c.o: +$(BUILDDIR)/%.o: $(SOURCEDIR)/%.c $(COMPILE) -c $< -o $@ - @$(COMPILE) -MM $< > $*.d + @$(COMPILE) -MM $< > $(BUILDDIR)/$*.d .S.o: - $(COMPILE) -x assembler-with-cpp -c $< -o $@ + $(COMPILE) -x assembler-with-cpp -c $< -o $(BUILDDIR)/$@ # "-x assembler-with-cpp" should not be necessary since this is the default # file type for the .S (with capital S) extension. However, upper case # characters are not always preserved on Windows. To ensure WinAVR # compatibility define the file type manually. -.c.s: - $(COMPILE) -S $< -o $@ +#.c.s: + $(COMPILE) -S $< -o $(BUILDDIR)/$@ flash: all $(AVRDUDE) -U flash:w:grbl.hex:i @@ -73,25 +77,25 @@ load: all bootloadHID grbl.hex clean: - rm -f grbl.hex main.elf $(OBJECTS) $(OBJECTS:.o=.d) + rm -f grbl.hex $(BUILDDIR)/* # file targets: -main.elf: $(OBJECTS) - $(COMPILE) -o main.elf $(OBJECTS) -lm -Wl,--gc-sections +$(BUILDDIR)/main.elf: $(OBJECTS) + $(COMPILE) -o $(BUILDDIR)/main.elf $(OBJECTS) -lm -Wl,--gc-sections -grbl.hex: main.elf +grbl.hex: $(BUILDDIR)/main.elf rm -f grbl.hex - avr-objcopy -j .text -j .data -O ihex main.elf grbl.hex - avr-size --format=berkeley main.elf + avr-objcopy -j .text -j .data -O ihex $(BUILDDIR)/main.elf grbl.hex + avr-size --format=berkeley $(BUILDDIR)/main.elf # If you have an EEPROM section, you must also create a hex file for the # EEPROM and add it to the "flash" target. # Targets for code debugging and analysis: disasm: main.elf - avr-objdump -d main.elf + avr-objdump -d $(BUILDDIR)/main.elf cpp: - $(COMPILE) -E main.c + $(COMPILE) -E $(SOURCEDIR)/main.c # include generated header dependencies --include $(OBJECTS:.o=.d) +-include $(BUILDDIR)/$(OBJECTS:.o=.d) diff --git a/README.md b/README.md index 1183789..1cfa679 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,8 @@ _**Archives:**_ - **New Grbl SIMULATOR! (by @jgeisler and @ashelly):** A completely independent wrapper of the Grbl main source code that may be compiled as an executable on a computer. No Arduino required. Simply simulates the responses of Grbl as if it was on an Arduino. May be used for many things: checking out how Grbl works, pre-process moves for GUI graphics, debugging of new features, etc. Much left to do, but potentially very powerful, as the dummy AVR variables can be written to output anything you need. - **Configurable Real-time Status Reporting:** Users can now customize the type of real-time data Grbl reports back when they issue a '?' status report. This includes data such as: machine position, work position, planner buffer usage, serial RX buffer usage. - **Updated Homing Routine:** Sets workspace volume in all negative space regardless of limit switch position. Common on pro CNCs. But, the behavior may be changed by a compile-time option though. Now tied directly into the main planner and stepper modules to reduce flash space and allow maximum speeds during seeking. + - **CoreXY Support:** Grbl now supports CoreXY kinematics on an introductory-level. Most functions have been verified to work, but there may be bugs here or there. Please report any problems you find! + - **Full Limit and Control Pin Configurability:** Limits and control pins operation can now be interpreted by Grbl however you'd like, with the internal pull-up resistors enabled or disabled, or reading a high or low as a trigger. This should cover all wiring and NO or NC switch scenarios. - **Optional Limit Pin Sharing:** Limit switches can be combined to share the same pins to free up precious I/O pins for other purposes. When combined, users must adjust the homing cycle mask in config.h to not home the axes on a shared pin at the same time. Don't worry; hard limits and the homing cycle still work just like they did before. - **Optional Variable Spindle Speed Output:** Available only as a compile-time option through the config.h file. Enables PWM output for 'S' g-code commands. Enabling this feature will swap the Z-limit D11 pin and spindle enable D12 pin to access the hardware PWM on pin D12. The Z-limit pin, now on D12, should work just as it did before. - **Additional Compile-Time Feature Options:** Line number tracking, real-time feed rate reporting. @@ -68,6 +70,7 @@ List of Supported G-Codes in Grbl v0.9 - Distance Modes: G90, G91 - Plane Select Modes: G17, G18, G19 - Tool Length Offset Modes: G43.1, G49 + - Cutter Compensation Modes: G40 - Coordinate System Modes: G54, G55, G56, G57, G58, G59 - Program Flow: M0, M1, M2, M30* - Coolant Control: M7*, M8, M9 diff --git a/examples/Grbl/Grbl.ino b/examples/Grbl/Grbl.ino deleted file mode 100644 index caf26fd..0000000 --- a/examples/Grbl/Grbl.ino +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include diff --git a/config.h b/grbl/config.h similarity index 98% rename from config.h rename to grbl/config.h index 0a0d886..a5c7f4e 100644 --- a/config.h +++ b/grbl/config.h @@ -185,9 +185,10 @@ // needs to connect a normal-open switch, but if inverted, this means the user should connect a // normal-closed switch. // The following options disable the internal pull-up resistors, sets the pins to a normal-low -// operation, and switches much be now connect to Vcc instead of ground. This also flips the meaning +// operation, and switches must be now connect to Vcc instead of ground. This also flips the meaning // of the invert pin Grbl setting, where an inverted setting now means the user should connect a // normal-open switch and vice versa. +// NOTE: All pins associated with the feature are disabled, i.e. XYZ limit pins, not individual axes. // WARNING: When the pull-ups are disabled, this requires additional wiring with pull-down resistors! //#define DISABLE_LIMIT_PIN_PULL_UP //#define DISABLE_PROBE_PIN_PULL_UP @@ -202,7 +203,7 @@ // enable pin will output 5V for maximum RPM with 256 intermediate levels and 0V when disabled. // NOTE: IMPORTANT for Arduino Unos! When enabled, the Z-limit pin D11 and spindle enable pin D12 switch! // The hardware PWM output on pin D11 is required for variable spindle output voltages. -// #define VARIABLE_SPINDLE // Default disabled. Uncomment to enable. +#define VARIABLE_SPINDLE // Default disabled. Uncomment to enable. // Used by the variable spindle output only. These parameters set the maximum and minimum spindle speed // "S" g-code values to correspond to the maximum and minimum pin voltages. There are 256 discrete and diff --git a/coolant_control.c b/grbl/coolant_control.c similarity index 100% rename from coolant_control.c rename to grbl/coolant_control.c diff --git a/coolant_control.h b/grbl/coolant_control.h similarity index 100% rename from coolant_control.h rename to grbl/coolant_control.h diff --git a/cpu_map.h b/grbl/cpu_map.h similarity index 100% rename from cpu_map.h rename to grbl/cpu_map.h diff --git a/defaults.h b/grbl/defaults.h similarity index 100% rename from defaults.h rename to grbl/defaults.h diff --git a/eeprom.c b/grbl/eeprom.c similarity index 100% rename from eeprom.c rename to grbl/eeprom.c diff --git a/eeprom.h b/grbl/eeprom.h similarity index 100% rename from eeprom.h rename to grbl/eeprom.h diff --git a/grbl/examples/grblUpload/grblUpload.ino b/grbl/examples/grblUpload/grblUpload.ino new file mode 100644 index 0000000..581b6b3 --- /dev/null +++ b/grbl/examples/grblUpload/grblUpload.ino @@ -0,0 +1,29 @@ +/*********************************************************************** +This sketch compiles and uploads Grbl to your 328p-based Arduino! + +To use: +- First make sure you have imported Grbl source code into your Arduino + IDE. There are details on our Github website on how to do this. + +- Select your Arduino Board and Serial Port in the Tools drop-down menu. + NOTE: Grbl only officially supports 328p-based Arduinos, like the Uno. + Using other boards will likely not work! + +- Then just click 'Upload'. That's it! + +For advanced users: + If you'd like to see what else Grbl can do, there are some additional + options for customization and features you can enable or disable. + Navigate your file system to where the Arduino IDE has stored the Grbl + source code files, open the 'config.h' file in your favorite text + editor. Inside are dozens of feature descriptions and #defines. Simply + comment or uncomment the #defines or alter their assigned values, save + your changes, and then click 'Upload' here. + +Copyright (c) 2015 Sungeun K. Jeon +Released under the MIT-license. See license.txt for details. +***********************************************************************/ + +#include + +// Do not alter this file! diff --git a/grbl/examples/grblUpload/license.txt b/grbl/examples/grblUpload/license.txt new file mode 100644 index 0000000..1abcdb9 --- /dev/null +++ b/grbl/examples/grblUpload/license.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Sungeun K. Jeon + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/gcode.c b/grbl/gcode.c similarity index 100% rename from gcode.c rename to grbl/gcode.c diff --git a/gcode.h b/grbl/gcode.h similarity index 100% rename from gcode.h rename to grbl/gcode.h diff --git a/grbl.h b/grbl/grbl.h similarity index 82% rename from grbl.h rename to grbl/grbl.h index 6295e7c..dc331bf 100644 --- a/grbl.h +++ b/grbl/grbl.h @@ -1,5 +1,5 @@ /* - grbl.h - include file + grbl.h - main Grbl include file Part of Grbl v0.9 Copyright (c) 2015 Sungeun K. Jeon @@ -18,13 +18,10 @@ along with Grbl. If not, see . */ -// NOTE: This is not used by the 'make' compiling method. This is currently only used for -// simplifying compiling through the Arduino IDE at the moment. However, it may eventually -// turn into a central include file for the overall system. - #ifndef grbl_h #define grbl_h +// Grbl versioning system #define GRBL_VERSION "0.9h" #define GRBL_VERSION_BUILD "20150210" @@ -41,7 +38,7 @@ #include #include -// Define the Grbl system include files. +// Define the Grbl system include files. NOTE: Do not alter organization. #include "config.h" #include "nuts_bolts.h" #include "settings.h" diff --git a/limits.c b/grbl/limits.c similarity index 99% rename from limits.c rename to grbl/limits.c index a8a2583..a8b2996 100644 --- a/limits.c +++ b/grbl/limits.c @@ -161,14 +161,14 @@ void limits_go_home(uint8_t cycle_mask) // Set target location for active axes and setup computation for homing rate. if (bit_istrue(cycle_mask,bit(idx))) { n_active_axis++; - if (!approach) { - // Set target direction based on cycle mask - if (bit_istrue(settings.homing_dir_mask,bit(idx))) { target[idx] += max_travel; } - else { target[idx] -= max_travel; } - } else { + if (approach) { // Set target direction based on cycle mask if (bit_istrue(settings.homing_dir_mask,bit(idx))) { target[idx] -= max_travel; } else { target[idx] += max_travel; } + } else { + // Set target direction based on cycle mask + if (bit_istrue(settings.homing_dir_mask,bit(idx))) { target[idx] += max_travel; } + else { target[idx] -= max_travel; } } } diff --git a/limits.h b/grbl/limits.h similarity index 100% rename from limits.h rename to grbl/limits.h diff --git a/main.c b/grbl/main.c similarity index 100% rename from main.c rename to grbl/main.c diff --git a/motion_control.c b/grbl/motion_control.c similarity index 100% rename from motion_control.c rename to grbl/motion_control.c diff --git a/motion_control.h b/grbl/motion_control.h similarity index 100% rename from motion_control.h rename to grbl/motion_control.h diff --git a/nuts_bolts.c b/grbl/nuts_bolts.c similarity index 100% rename from nuts_bolts.c rename to grbl/nuts_bolts.c diff --git a/nuts_bolts.h b/grbl/nuts_bolts.h similarity index 100% rename from nuts_bolts.h rename to grbl/nuts_bolts.h diff --git a/planner.c b/grbl/planner.c similarity index 100% rename from planner.c rename to grbl/planner.c diff --git a/planner.h b/grbl/planner.h similarity index 100% rename from planner.h rename to grbl/planner.h diff --git a/print.c b/grbl/print.c similarity index 100% rename from print.c rename to grbl/print.c diff --git a/print.h b/grbl/print.h similarity index 100% rename from print.h rename to grbl/print.h diff --git a/probe.c b/grbl/probe.c similarity index 100% rename from probe.c rename to grbl/probe.c diff --git a/probe.h b/grbl/probe.h similarity index 100% rename from probe.h rename to grbl/probe.h diff --git a/protocol.c b/grbl/protocol.c similarity index 100% rename from protocol.c rename to grbl/protocol.c diff --git a/protocol.h b/grbl/protocol.h similarity index 100% rename from protocol.h rename to grbl/protocol.h diff --git a/report.c b/grbl/report.c similarity index 100% rename from report.c rename to grbl/report.c diff --git a/report.h b/grbl/report.h similarity index 100% rename from report.h rename to grbl/report.h diff --git a/serial.c b/grbl/serial.c similarity index 100% rename from serial.c rename to grbl/serial.c diff --git a/serial.h b/grbl/serial.h similarity index 100% rename from serial.h rename to grbl/serial.h diff --git a/settings.c b/grbl/settings.c similarity index 100% rename from settings.c rename to grbl/settings.c diff --git a/settings.h b/grbl/settings.h similarity index 100% rename from settings.h rename to grbl/settings.h diff --git a/spindle_control.c b/grbl/spindle_control.c similarity index 100% rename from spindle_control.c rename to grbl/spindle_control.c diff --git a/spindle_control.h b/grbl/spindle_control.h similarity index 100% rename from spindle_control.h rename to grbl/spindle_control.h diff --git a/stepper.c b/grbl/stepper.c similarity index 100% rename from stepper.c rename to grbl/stepper.c diff --git a/stepper.h b/grbl/stepper.h similarity index 100% rename from stepper.h rename to grbl/stepper.h diff --git a/system.c b/grbl/system.c similarity index 100% rename from system.c rename to grbl/system.c diff --git a/system.h b/grbl/system.h similarity index 100% rename from system.h rename to grbl/system.h From 20c7750dabf3491df373b94b6527c1544a7e5716 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Tue, 10 Feb 2015 22:10:03 -0700 Subject: [PATCH 23/40] Git fix for empty directory. Makefile updated. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ‘build’ directory was not being synced by git because it was empty. Added a .gitignore file in the ‘build’ directory to force git to sync it but keep it empty. - Updated the Makefile to not erase the .gitignore. --- Makefile | 2 +- build/.gitignore | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 build/.gitignore diff --git a/Makefile b/Makefile index d825ee5..504bb99 100644 --- a/Makefile +++ b/Makefile @@ -77,7 +77,7 @@ load: all bootloadHID grbl.hex clean: - rm -f grbl.hex $(BUILDDIR)/* + rm -f grbl.hex $(BUILDDIR)/*.o $(BUILDDIR)/*.d $(BUILDDIR)/*.elf # file targets: $(BUILDDIR)/main.elf: $(OBJECTS) diff --git a/build/.gitignore b/build/.gitignore new file mode 100644 index 0000000..86d0cb2 --- /dev/null +++ b/build/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore \ No newline at end of file From 4bdc20ffb94f70eaf99ad2c19d96f6c951f191c5 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Wed, 11 Feb 2015 21:19:00 -0700 Subject: [PATCH 24/40] Overhauled state machine. New safety door feature. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Overhauled the state machine and cleaned up its overall operation. This involved creating a new ‘suspend’ state for what all external commands, except real-time commands, are ignored. All hold type states enter this suspend state. - Removed ‘auto cycle start’ setting from Grbl. This was not used by users in its intended way and is somewhat redundant, as GUI manage the cycle start by streaming. It also muddled up how Grbl should interpret how and when to execute a g-code block. Removing it made everything much much simpler. - Fixed a program pause bug when used with other buffer_sync commands. - New safety door feature for OEMs. Immediately forces a feed hold and then de-energizes the machine. Resuming is blocked until the door is closed. When it is, it re-energizes the system and then resumes on the normal toolpath. - Safety door input pin is optional and uses the feed hold pin on A1. Enabled by config.h define. - Spindle and coolant re-energizing upon a safety door resume has a programmable delay time to allow for complete spin up to rpm and turning on the coolant before resuming motion. - Safety door-style feed holds can be used instead of regular feed hold (doesn’t de-energize the machine) with a ‘@‘ character. If the safety door input pin is not enabled, the system can be resumed at any time. --- grbl/config.h | 13 ++++ grbl/cpu_map.h | 3 +- grbl/gcode.c | 6 +- grbl/limits.c | 10 ++- grbl/main.c | 3 +- grbl/motion_control.c | 14 +--- grbl/probe.c | 2 +- grbl/protocol.c | 163 ++++++++++++++++++++++++++++++++---------- grbl/report.c | 8 ++- grbl/report.h | 1 + grbl/serial.c | 1 + grbl/settings.c | 5 -- grbl/settings.h | 2 +- grbl/stepper.c | 31 ++++---- grbl/system.c | 37 +++++++++- grbl/system.h | 30 +++++--- 16 files changed, 237 insertions(+), 92 deletions(-) diff --git a/grbl/config.h b/grbl/config.h index a5c7f4e..0635c65 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -54,6 +54,7 @@ #define CMD_FEED_HOLD '!' #define CMD_CYCLE_START '~' #define CMD_RESET 0x18 // ctrl-x. +#define CMD_SAFETY_DOOR '@' //0x13 // ctrl-s // If homing is enabled, homing init lock sets Grbl into an alarm state upon power up. This forces // the user to perform the homing cycle (or override the locks) before doing anything else. This is @@ -133,6 +134,18 @@ // NOTE: The M8 flood coolant control pin on analog pin 4 will still be functional regardless. // #define ENABLE_M7 // Disabled by default. Uncomment to enable. +// This option causes the feed hold input to act as a safety door switch. A safety door, when triggered, +// immediately forces a feed hold and then safely de-energizes the machine. Resuming is blocked until +// the safety door is re-engaged. When it is, Grbl will re-energize the machine and then resume on the +// previous tool path, as if nothing happened. +// #define ENABLE_SAFETY_DOOR_INPUT_PIN // Default disabled. Uncomment to enable. + +// After the safety door switch has been toggled and restored, this setting sets the power-up delay +// between restoring the spindle and coolant and resuming the cycle. +// NOTE: Delay value is defined in milliseconds from zero to 65,535. +#define SAFETY_DOOR_SPINDLE_DELAY 4000 // Disabled by default. Comment to enable. +#define SAFETY_DOOR_COOLANT_DELAY 1000 // Disabled by default. Comment to enable. + // Enable CoreXY kinematics. Use ONLY with CoreXY machines. // IMPORTANT: If homing is enabled, you must reconfigure the homing cycle #defines above to // #define HOMING_CYCLE_0 (1<entry_speed_sqr = prep.exit_speed*prep.exit_speed; @@ -587,7 +593,7 @@ void st_prep_buffer() */ prep.mm_complete = 0.0; // Default velocity profile complete at 0.0mm from end of block. float inv_2_accel = 0.5/pl_block->acceleration; - if (sys.state == STATE_HOLD) { // [Forced Deceleration to Zero Velocity] + if (sys.state & (STATE_HOLD|STATE_MOTION_CANCEL|STATE_SAFETY_DOOR)) { // [Forced Deceleration to Zero Velocity] // Compute velocity profile parameters for a feed hold in-progress. This profile overrides // the planner block profile, enforcing a deceleration to zero speed. prep.ramp_type = RAMP_DECEL; @@ -746,16 +752,14 @@ void st_prep_buffer() // Bail if we are at the end of a feed hold and don't have a step to execute. if (prep_segment->n_step == 0) { - if (sys.state == STATE_HOLD) { - + if (sys.state & (STATE_HOLD|STATE_MOTION_CANCEL|STATE_SAFETY_DOOR)) { // Less than one step to decelerate to zero speed, but already very close. AMASS // requires full steps to execute. So, just bail. - prep.current_speed = 0.0; + prep.current_speed = 0.0; // NOTE: (=0.0) Used to indicate completed segment calcs for hold. prep.dt_remainder = 0.0; prep.steps_remaining = n_steps_remaining; pl_block->millimeters = prep.steps_remaining/prep.step_per_mm; // Update with full steps. plan_cycle_reinitialize(); - sys.state = STATE_QUEUED; return; // Segment not generated, but current step data still retained. } } @@ -818,21 +822,18 @@ void st_prep_buffer() } else { // End of planner block or forced-termination. No more distance to be executed. if (mm_remaining > 0.0) { // At end of forced-termination. - // Reset prep parameters for resuming and then bail. - // NOTE: Currently only feed holds qualify for this scenario. May change with overrides. - prep.current_speed = 0.0; + // Reset prep parameters for resuming and then bail. Allow the stepper ISR to complete + // the segment queue, where realtime protocol will set new state upon receiving the + // cycle stop flag from the ISR. Prep_segment is blocked until then. + prep.current_speed = 0.0; // NOTE: (=0.0) Used to indicate completed segment calcs for hold. prep.dt_remainder = 0.0; prep.steps_remaining = ceil(steps_remaining); pl_block->millimeters = prep.steps_remaining/prep.step_per_mm; // Update with full steps. plan_cycle_reinitialize(); - sys.state = STATE_QUEUED; // End cycle. - return; // Bail! -// TODO: Try to move QUEUED setting into cycle re-initialize. - } else { // End of planner block // The planner block is complete. All steps are set to be executed in the segment buffer. - pl_block = NULL; + pl_block = NULL; // Set pointer to indicate check and load next planner block. plan_discard_current_block(); } } @@ -848,7 +849,7 @@ void st_prep_buffer() #ifdef REPORT_REALTIME_RATE float st_get_realtime_rate() { - if (sys.state & (STATE_CYCLE | STATE_HOMING | STATE_HOLD)){ + if (sys.state & (STATE_CYCLE | STATE_HOMING | STATE_HOLD | STATE_MOTION_CANCEL | STATE_SAFETY_DOOR)){ return prep.current_speed; } return 0.0f; diff --git a/grbl/system.c b/grbl/system.c index bec36d6..7a09162 100644 --- a/grbl/system.c +++ b/grbl/system.c @@ -48,15 +48,35 @@ ISR(CONTROL_INT_vect) if (pin) { if (bit_istrue(pin,bit(RESET_BIT))) { mc_reset(); - } else if (bit_istrue(pin,bit(FEED_HOLD_BIT))) { - bit_true(sys.rt_exec_state, EXEC_FEED_HOLD); } else if (bit_istrue(pin,bit(CYCLE_START_BIT))) { bit_true(sys.rt_exec_state, EXEC_CYCLE_START); + #ifndef ENABLE_SAFETY_DOOR_INPUT_PIN + } else if (bit_istrue(pin,bit(FEED_HOLD_BIT))) { + bit_true(sys.rt_exec_state, EXEC_FEED_HOLD); + #else + } else if (bit_istrue(pin,bit(SAFETY_DOOR_BIT))) { + bit_true(sys.rt_exec_state, EXEC_SAFETY_DOOR); + #endif } } } +// Returns if safety door is ajar(T) or closed(F), based on pin state. +uint8_t system_check_safety_door_ajar() +{ + #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN + #ifdef INVERT_CONTROL_PIN + return(bit_istrue(CONTROL_PIN,bit(SAFETY_DOOR_BIT))); + #else + return(bit_isfalse(CONTROL_PIN,bit(SAFETY_DOOR_BIT))); + #endif + #else + return(false); // Input pin not enabled, so just return that it's closed. + #endif +} + + // Executes user startup script, if stored. void system_execute_startup(char *line) { @@ -95,6 +115,7 @@ uint8_t system_execute_line(char *line) else { report_grbl_settings(); } break; case 'G' : // Prints gcode parser state + // TODO: Move this to realtime commands for GUIs to request this data during suspend-state. if ( line[++char_counter] != 0 ) { return(STATUS_INVALID_STATEMENT); } else { report_gcode_modes(); } break; @@ -118,6 +139,10 @@ uint8_t system_execute_line(char *line) report_feedback_message(MESSAGE_ALARM_UNLOCK); sys.state = STATE_IDLE; // Don't run startup script. Prevents stored moves in startup from causing accidents. + if (system_check_safety_door_ajar()) { // Check safety door switch before returning. + bit_true(sys.rt_exec_state, EXEC_SAFETY_DOOR); + protocol_execute_realtime(); // Enter safety door mode. + } } // Otherwise, no effect. break; // case 'J' : break; // Jogging methods @@ -144,6 +169,14 @@ uint8_t system_execute_line(char *line) if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { sys.state = STATE_HOMING; // Set system state variable // Only perform homing if Grbl is idle or lost. + + // TODO: Likely not required. + if (system_check_safety_door_ajar()) { // Check safety door switch before homing. + bit_true(sys.rt_exec_state, EXEC_SAFETY_DOOR); + protocol_execute_realtime(); // Enter safety door mode. + } + + mc_homing_cycle(); if (!sys.abort) { // Execute startup scripts after successful homing. sys.state = STATE_IDLE; // Set to IDLE when complete. diff --git a/grbl/system.h b/grbl/system.h index 2c2a89d..58b67d1 100644 --- a/grbl/system.h +++ b/grbl/system.h @@ -33,6 +33,8 @@ #define EXEC_CYCLE_STOP bit(2) // bitmask 00000100 #define EXEC_FEED_HOLD bit(3) // bitmask 00001000 #define EXEC_RESET bit(4) // bitmask 00010000 +#define EXEC_SAFETY_DOOR bit(5) // bitmask 00100000 +#define EXEC_MOTION_CANCEL bit(6) // bitmask 01000000 // Alarm executor bit map. // NOTE: EXEC_CRITICAL_EVENT is an optional flag that must be set with an alarm flag. When enabled, @@ -47,27 +49,34 @@ // Define system state bit map. The state variable primarily tracks the individual functions // of Grbl to manage each without overlapping. It is also used as a messaging flag for // critical events. -#define STATE_IDLE 0 // Must be zero. No flags. -#define STATE_ALARM bit(0) // In alarm state. Locks out all g-code processes. Allows settings access. -#define STATE_CHECK_MODE bit(1) // G-code check mode. Locks out planner and motion only. -#define STATE_HOMING bit(2) // Performing homing cycle -#define STATE_QUEUED bit(3) // Indicates buffered blocks, awaiting cycle start. -#define STATE_CYCLE bit(4) // Cycle is running -#define STATE_HOLD bit(5) // Executing feed hold -// #define STATE_JOG bit(6) // Jogging mode is unique like homing. +#define STATE_IDLE 0 // Must be zero. No flags. +#define STATE_ALARM bit(0) // In alarm state. Locks out all g-code processes. Allows settings access. +#define STATE_CHECK_MODE bit(1) // G-code check mode. Locks out planner and motion only. +#define STATE_HOMING bit(2) // Performing homing cycle +#define STATE_CYCLE bit(3) // Cycle is running or motions are being executed. +#define STATE_HOLD bit(4) // Active feed hold +#define STATE_SAFETY_DOOR bit(5) // Safety door is ajar. Feed holds and de-energizes system. +#define STATE_MOTION_CANCEL bit(6) // Motion cancel by feed hold and return to idle. + +// Define system suspend states. +#define SUSPEND_DISABLE 0 // Must be zero. +#define SUSPEND_ENABLE_HOLD bit(0) // Enabled. Indicates the cycle is active and currently undergoing a hold. +#define SUSPEND_ENABLE_READY bit(1) // Ready to resume with a cycle start command. +#define SUSPEND_ENERGIZE bit(2) // Re-energizes output before resume. +#define SUSPEND_MOTION_CANCEL bit(3) // Cancels resume motion. Used by probing routine. // Define global system variables typedef struct { uint8_t abort; // System abort flag. Forces exit back to main loop for reset. uint8_t state; // Tracks the current state of Grbl. + uint8_t suspend; // System suspend flag. Allows only realtime commands. Used primarily for holds. volatile uint8_t rt_exec_state; // Global realtime executor bitflag variable for state management. See EXEC bitmasks. volatile uint8_t rt_exec_alarm; // Global realtime executor bitflag variable for setting various alarms. int32_t position[N_AXIS]; // Real-time machine (aka home) position vector in steps. // NOTE: This may need to be a volatile variable, if problems arise. - uint8_t auto_start; // Planner auto-start flag. Toggled off during feed hold. Defaulted by settings. uint8_t homing_axis_lock; // Locks axes when limits engage. Used as an axis motion mask in the stepper ISR. volatile uint8_t probe_state; // Probing state value. Used to coordinate the probing cycle with stepper ISR. @@ -80,6 +89,9 @@ extern system_t sys; // Initialize the serial protocol void system_init(); +// Returns if safety door is open or closed, based on pin state. +uint8_t system_check_safety_door_ajar(); + // Executes an internal system command, defined as a string starting with a '$' uint8_t system_execute_line(char *line); From fe16b7db5ca79e814b34db24117ad68ca8773fed Mon Sep 17 00:00:00 2001 From: Rob Brown Date: Fri, 13 Feb 2015 16:17:07 +0800 Subject: [PATCH 25/40] Safety Door Update for Mega2560 --- grbl/cpu_map.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/grbl/cpu_map.h b/grbl/cpu_map.h index a10568e..6c9134c 100644 --- a/grbl/cpu_map.h +++ b/grbl/cpu_map.h @@ -222,16 +222,17 @@ #define RESET_BIT 0 // MEGA2560 Analog Pin 8 #define FEED_HOLD_BIT 1 // MEGA2560 Analog Pin 9 #define CYCLE_START_BIT 2 // MEGA2560 Analog Pin 10 + #define SAFETY_DOOR_BIT 3 // MEGA2560 Analog Pin 11 #define CONTROL_INT PCIE2 // Pin change interrupt enable pin #define CONTROL_INT_vect PCINT2_vect #define CONTROL_PCMSK PCMSK2 // Pin change interrupt register - #define CONTROL_MASK ((1< Date: Fri, 13 Feb 2015 22:50:07 +0100 Subject: [PATCH 26/40] Fix EXEC_ALARM_* flags: soft limit would lead to hard limit error. --- grbl/system.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/grbl/system.h b/grbl/system.h index 58b67d1..d6e190e 100644 --- a/grbl/system.h +++ b/grbl/system.h @@ -41,10 +41,10 @@ // this halts Grbl into an infinite loop until the user aknowledges the problem and issues a soft- // reset command. For example, a hard limit event needs this type of halt and aknowledgement. #define EXEC_CRITICAL_EVENT bit(0) // bitmask 00000001 (SPECIAL FLAG. See NOTE:) -#define EXEC_ALARM_HARD_LIMIT bit(0) // bitmask 00000010 -#define EXEC_ALARM_SOFT_LIMIT bit(1) // bitmask 00000100 -#define EXEC_ALARM_ABORT_CYCLE bit(2) // bitmask 00001000 -#define EXEC_ALARM_PROBE_FAIL bit(3) // bitmask 00010000 +#define EXEC_ALARM_HARD_LIMIT bit(1) // bitmask 00000010 +#define EXEC_ALARM_SOFT_LIMIT bit(2) // bitmask 00000100 +#define EXEC_ALARM_ABORT_CYCLE bit(3) // bitmask 00001000 +#define EXEC_ALARM_PROBE_FAIL bit(4) // bitmask 00010000 // Define system state bit map. The state variable primarily tracks the individual functions // of Grbl to manage each without overlapping. It is also used as a messaging flag for From cff926f86159575ca29c75ec8571727a6a2e7049 Mon Sep 17 00:00:00 2001 From: Martin Poelstra Date: Fri, 13 Feb 2015 22:53:59 +0100 Subject: [PATCH 27/40] Fix generating header dependencies, merge with 'normal' compile, force recompile when files are removed. --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 504bb99..79fb3bf 100644 --- a/Makefile +++ b/Makefile @@ -50,8 +50,7 @@ OBJECTS = $(addprefix $(BUILDDIR)/,$(notdir $(SOURCE:.c=.o))) all: grbl.hex $(BUILDDIR)/%.o: $(SOURCEDIR)/%.c - $(COMPILE) -c $< -o $@ - @$(COMPILE) -MM $< > $(BUILDDIR)/$*.d + $(COMPILE) -MMD -MP -c $< -o $@ .S.o: $(COMPILE) -x assembler-with-cpp -c $< -o $(BUILDDIR)/$@ From 56c4bfc7b97a8c9304f405f15d3639702f03ef18 Mon Sep 17 00:00:00 2001 From: Martin Poelstra Date: Fri, 13 Feb 2015 22:57:11 +0100 Subject: [PATCH 28/40] Fix function signature of print_uint32_base10(), necessary for compiling simulator. --- grbl/print.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grbl/print.c b/grbl/print.c index 781cedc..35d1c1c 100644 --- a/grbl/print.c +++ b/grbl/print.c @@ -100,7 +100,7 @@ void print_uint8_base10(uint8_t n) } -void print_uint32_base10(unsigned long n) +void print_uint32_base10(uint32_t n) { if (n == 0) { serial_write('0'); From 565519c1449173d8a91b5b39decbb2f8a1487ff2 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Fri, 13 Feb 2015 18:39:37 -0700 Subject: [PATCH 29/40] Doc re-org. New Grbl Logos! --- doc/logo/Grbl Logo 150px.png | Bin 0 -> 10481 bytes doc/logo/Grbl Logo 320px.png | Bin 0 -> 58580 bytes doc/logo/Grbl Logo 640px.png | Bin 0 -> 48868 bytes doc/logo/Grbl Logo.pdf | Bin 0 -> 4837 bytes doc/logo/Grbl Logo.svg | 134 ++++++++++++++++++++++++ {script => doc/script}/simple_stream.py | 0 {script => doc/script}/stream.py | 0 grbl/config.h | 6 +- 8 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 doc/logo/Grbl Logo 150px.png create mode 100644 doc/logo/Grbl Logo 320px.png create mode 100644 doc/logo/Grbl Logo 640px.png create mode 100644 doc/logo/Grbl Logo.pdf create mode 100644 doc/logo/Grbl Logo.svg rename {script => doc/script}/simple_stream.py (100%) rename {script => doc/script}/stream.py (100%) diff --git a/doc/logo/Grbl Logo 150px.png b/doc/logo/Grbl Logo 150px.png new file mode 100644 index 0000000000000000000000000000000000000000..999886e6cb8cb83f97ad83b22c9300f42d83f506 GIT binary patch literal 10481 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 z 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 literal 0 HcmV?d00001 diff --git a/doc/logo/Grbl Logo 640px.png b/doc/logo/Grbl Logo 640px.png new file mode 100644 index 0000000000000000000000000000000000000000..96a386a11e466452e8acc902f7b156a77fc280a5 GIT binary patch literal 48868 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 w;Fm~``jsYYKs7P9%_QhyVry zcBhbuI2W)tvwytqZBZ0g@UjQk5-1bDwbpCv$@~OrJIIRQ@^0t&+*;d1Ynq7hakh@I zM675J(T0zFv%s`?X>IsbL?qLzi{~}I$7f-hN)9WDw^$j{Nvn(Vcj-%>_s`9H`ZCEB z^L+O9uQ9?zDh=`2ooW;%uVWpH%_=&l9G||~{RW}?w8cO5XlDM!(~gsl{@UXfDMEP| z3T0qvkGPu{Da*Ly)Cd`9@dL@rZ>>}r0zCZnf@$Hhn$-Hb^CDrF63Oc(+5b@as-`uHH*>>? zxzI)@p!1%I;N@toa*wrE?gj3%*dTU6yv<6us1J8uocksqby8YVB*I_!#s)r*9P zYsMecI;b9=C*~{X?CMP8PYJB(T`Py?1`j1tBMv4RR~i4=sz{D(SMNM!X!G8J6J7=r z7}SzBl-zsYp|u9^RX`rSQHdJV7xuHIV(u-xGEvZq%CYaNb~bbyDw&1^QOiFp`rTVf z+LU)u5?P%s4D0izdfA!H^#^XuOZL;_nV4|zd&t1uAZExo79lZTULs8qE z+fDdy`~3Ws%S1p%A7{7oBokdJfb5SwZ%A|}d5{T2cR=okK#k-|Vf4EL+jW9b6m*F; z4meekH((BB2#{zb1dc+=0rChKL|z^(ZvmE3Ba<%gD4?Jaq#RTZ4Z!7*5R@DWK*He= zG)fi?AmvaHs4Ns^0m!I26Nxte)!uosgUf$W0Ay6il>gSxC|N&4usx+;rB0trA{Y@V zfH@-$>Y4z<6E%`EiEMNkM<4>*wNT9+2B3E4jKOS|y`MJZf3xwkT%vchWX>^SD5J7n zGF=(<5|B|RdO8q@hFI1AT}e~#dYw1w6%3_OQPj78hyfCd!af|pyVGX`Kn7u2*YsIJ zf+RiFcWLtT9W%B$|B4wKDn`)Y=e%(p-@`G_tKV2-psqphi*VwYDMT*xCvP^H4)l&a z@9DLh@$ac%(%-las->7PUqhsu@PD1Gx%9{0milFueZ0)vCd{t}ZEZo=6?K-*4XR>N zQtp|?(xtDEYc`c1rK|NN-MhB}qQy{Z;=7r^8eMVfZ#?@yK(%!~k~UrLntY?tZBMx>tC zN@k)jAMNN^xu?SfigsTm;=bvC^VB05svy&nxLL}9(yI6iOl2;+mFa_z^kx92 z`CUw9{r46QhB#Zs)DJOgZ1~iavpaK|6Xe7f)Oy-=(wpiK^m0vt_h$|SIoGiKafgla0E`HPKv|@%_lRDTz0BGV zFa=#Z!^?V?6>^5fK^gQ!1@oQ>tO9$_?0LiSGE--u&s)&B>vETOUjkixwdXP?*EOs% zIHcw*l(|39f&Ka{uRw-M{vE+Ao+Q<7UJ*0)D{3nG^8Bm~YGHSHW0Y6lO6Kl6ej`6! zOI+U zToA+kyjEyXWR^)f*s3;`UAdW^wO!MMU1UyO^^S=+Gv8sSXt6AoJdNZ#+*u+oBF{v- zjj-+xO~)nf6Kvc+9BLXdh&RS{((e zM4qfSwvMtkFG+aJ`W`oRT9mu#)&3#T%U8?yU4pwJi$KqLdLk;XP1fxhl$`T^dAy&0 z<~mP}`z+q?a1}T}G~nPs)S<>|sXH8IAgAj*hwlR7&f@2Jh1tj0H-q?U5e9*|dK9q` z-YfN&@W&qCey{RUOH}e)EWcKWxR9avv81xV^IDE#7LtmR)Wfl_PuXC}`%INB^@_yP z04oWe7$yCEm0$%)ld?J-p#432qnyQ{M!Ci)FtfxsU30LkRxwyhBRL}; ze-odK55wOWLN*vkyo?EqdH#o9p7MCfJBf#fg;hHqUU^qurdxLE1Mvg&02Y7{QBch^F#S7Z(MKa7ZtsEmkOK#abi4bwi#6+2jNy*w7b zdffH6U%XhnZ9H>)RKCsyQWt+$YQ9UpUMJL1(h=v_>$u(pDTt)y(7f)`QmqhMBO9R; zB^6;lLwH?Vuh21tAzIpUl2|}G$QvWyC%O*rYDafn#%0WIG=*d=w@S2EuryA zUt7=HN|c79(+i8Hb56Envib@X3kkWUCU%+UO565Y#6ZkZD$g%HH}X=|J1b)%V^wT0 zla4V+D@@C(##WmLym|E&_+TBbl2VhKek;8icOREINH~%oUC@3!(=79Jqdei6+pRgw zu(@POSgKZxR^)44qxYTt=dCMfWi&3QQF}>50kX0wqvVsR=_AeV2k1J5X1~lUDXS+q z6~j%!Qw943t)!==jZRKVA2K~=y353+Y@%eX?n8aDlLf)QDa3J@P}-K=H~O?N@8p1I z^|b%#WQ&qM!OC-$v?cB(v31FH7@K0KcPN#6`8~z+Xl0Op7vJQU!Sc4bh+#Gt1=DrUijd&zEb*21*_f>B%&`G?8x>|kZnW*M>&Diir!Lx#1ny;}9 z8eLdj4PT7}jk5_R(x#;&nh|CZK(?abArS#zaZhsI^1HsXp~F){;NhVk~mbVuiR74N3@l z64b7qP;U`N&??dr&>CjZQ+fK?wz}t(0}BO5kploUo8p zl%mSiAu^$A6>l86zFydyq1+y=bJX3`wleYdcb#u%BE(Z9ZkTeGIzH*Q!xGcp7_{<@ zE{-IRxV9X4z3_VdD$*9|_1^{te$U zbZbaY;#17zfT{n*)xOrHplRyErHAWYpFP>VKJ|@PESMzWO)Y!h7JarTq_@sz%s;QZ zI8|kgGk3G*afq^sDud@fp=uX9V!LuCvL*tBqmoCd6TZ) z9OM^$8PL3}?^LMb(t!Ik_^6IHnK4mOZ5Ln_pgw(OE}Di7#y)JSjq>O^-Pwc6Ma9Y0 zM#eNg9(HRYZGQfy=DW9GTwgZx#R^FNFnVsNY30z&eJ+LGE4Tdf$E7yYmY%&eyJeQ% z{i!?bS(coGua57)__dDI18oORDy3}sEk-OQC6~UjJ4=gh6S$XxPV>4tui6+q7ak@Q zdg>wtQ&BeZF14tnsJ|sJq1bZn1v&2{b$#PPLV;Zo+Tyf-sy}r)WHYk+VCDV0R#R6U z#-Gl(P{%KqZr&X(yj``+e{9WSU8aAj!k>P7D^-LweD~T{NR{uF<47vaVWX?L+xHI7MHm_jV`wb$)wwb}-ZK~lYIA@aG56xKuGSLJ`S91 + + + + + image/svg+xml + + + + + + + /Users/chamnit/Dropbox/documents/OHS/Logo/Grbl.DXF - scale = 58.043118, origin = (0.000000, 0.000000), auto = True + + + + + + + + + + + + + + + + + + + + + + + diff --git a/script/simple_stream.py b/doc/script/simple_stream.py similarity index 100% rename from script/simple_stream.py rename to doc/script/simple_stream.py diff --git a/script/stream.py b/doc/script/stream.py similarity index 100% rename from script/stream.py rename to doc/script/stream.py diff --git a/grbl/config.h b/grbl/config.h index 0635c65..946e25a 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -54,7 +54,7 @@ #define CMD_FEED_HOLD '!' #define CMD_CYCLE_START '~' #define CMD_RESET 0x18 // ctrl-x. -#define CMD_SAFETY_DOOR '@' //0x13 // ctrl-s +#define CMD_SAFETY_DOOR '@' // If homing is enabled, homing init lock sets Grbl into an alarm state upon power up. This forces // the user to perform the homing cycle (or override the locks) before doing anything else. This is @@ -143,8 +143,8 @@ // After the safety door switch has been toggled and restored, this setting sets the power-up delay // between restoring the spindle and coolant and resuming the cycle. // NOTE: Delay value is defined in milliseconds from zero to 65,535. -#define SAFETY_DOOR_SPINDLE_DELAY 4000 // Disabled by default. Comment to enable. -#define SAFETY_DOOR_COOLANT_DELAY 1000 // Disabled by default. Comment to enable. +#define SAFETY_DOOR_SPINDLE_DELAY 4000 +#define SAFETY_DOOR_COOLANT_DELAY 1000 // Enable CoreXY kinematics. Use ONLY with CoreXY machines. // IMPORTANT: If homing is enabled, you must reconfigure the homing cycle #defines above to From 5a547dbb3396dff01d2fd4f8fdfa7255a6a3be44 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Fri, 13 Feb 2015 18:45:55 -0700 Subject: [PATCH 30/40] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1cfa679..ae6b692 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -#Grbl - An embedded g-code interpreter and motion-controller for the Arduino/AVR328 microcontroller +![GitHub Logo](/doc/logo/Grbl Logo 320px.png) + *** From fd02c3a47ec4eab48ffd87ac1720e81ca03c0cfb Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Fri, 13 Feb 2015 18:48:15 -0700 Subject: [PATCH 31/40] Updated README with new logo sized for github. --- README.md | 2 +- doc/logo/Grbl Logo 250px.png | Bin 0 -> 42049 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 doc/logo/Grbl Logo 250px.png diff --git a/README.md b/README.md index ae6b692..e03cc0f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![GitHub Logo](/doc/logo/Grbl Logo 320px.png) +![GitHub Logo](/doc/logo/Grbl Logo 250px.png) *** diff --git a/doc/logo/Grbl Logo 250px.png b/doc/logo/Grbl Logo 250px.png new file mode 100644 index 0000000000000000000000000000000000000000..bc9319b3d7c5593ea2b521ca856b2685297d2fc6 GIT binary patch literal 42049 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 Date: Sun, 15 Feb 2015 17:36:08 -0700 Subject: [PATCH 32/40] Homing alarm upon no switch. Licensing update. - Homing cycle failure reports alarm feedback when the homing cycle is exited via a reset, interrupted by a safety door switch, or does not find the limit switch. - Homing cycle bug fix when not finding the limit switch. It would just idle before, but now will exit with an alarm. - Licensing update. Corrected licensing according to lawyer recommendations. Removed references to other Grbl versions. --- COPYING | 45 +++++++++--------------------------------- grbl/config.h | 11 +++-------- grbl/coolant_control.c | 2 +- grbl/coolant_control.h | 2 +- grbl/cpu_map.h | 2 +- grbl/defaults.h | 2 +- grbl/eeprom.h | 28 ++++++++++---------------- grbl/gcode.c | 13 ++++-------- grbl/gcode.h | 11 +++-------- grbl/grbl.h | 2 +- grbl/limits.c | 16 ++++++--------- grbl/limits.h | 10 +++------- grbl/main.c | 13 ++++-------- grbl/motion_control.c | 16 ++++++--------- grbl/motion_control.h | 11 +++-------- grbl/nuts_bolts.c | 11 +++-------- grbl/nuts_bolts.h | 11 +++-------- grbl/planner.c | 13 ++++-------- grbl/planner.h | 11 +++-------- grbl/print.c | 11 +++-------- grbl/print.h | 11 +++-------- grbl/probe.c | 2 +- grbl/probe.h | 2 +- grbl/protocol.c | 15 ++++++-------- grbl/protocol.h | 11 +++-------- grbl/report.c | 4 +++- grbl/report.h | 3 ++- grbl/serial.c | 11 +++-------- grbl/serial.h | 11 +++-------- grbl/settings.c | 11 +++-------- grbl/settings.h | 11 +++-------- grbl/spindle_control.c | 9 ++------- grbl/spindle_control.h | 9 ++------- grbl/stepper.c | 11 +++-------- grbl/stepper.h | 11 +++-------- grbl/system.c | 2 +- grbl/system.h | 3 ++- 37 files changed, 116 insertions(+), 262 deletions(-) diff --git a/COPYING b/COPYING index 8bc8392..cdf88d6 100644 --- a/COPYING +++ b/COPYING @@ -1,56 +1,31 @@ ------------------------------------------------------------------------------ -COPYRIGHT NOTICE FOR GRBL v0.9: +COPYRIGHT NOTICE FOR GRBL: ------------------------------------------------------------------------------ -GRBL v0.9 - Embedded CNC g-code interpreter and motion-controller -Copyright (c) 2012-2014 Sungeun K. Jeon +Grbl - Embedded CNC g-code interpreter and motion-controller -This program is free software: you can redistribute it and/or modify +Copyright (c) 2011-2015 Sungeun K. Jeon +Copyright (c) 2009-2011 Simen Svale Skogsrud +Copyright (c) 2011 Jens Geisler + +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. -This program is distributed in the hope that it will be useful, +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 this program. If not, see . - +along with Grbl. If not, see . ------------------------------------------------------------------------------ COPYRIGHT NOTICE(S) FOR WORK CONTAINED IN THIS SOFTWARE: ------------------------------------------------------------------------------ -The MIT License (MIT) - -GRBL(tm) v0.8 - Embedded CNC g-code interpreter and motion-controller -Copyright (c) 2009-2011 Simen Svale Skogsrud -Copyright (c) 2011-2013 Sungeun K. Jeon -Copyright (c) 2011 Jens Geisler - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -------------- - Copyright (c) 2008, Atmel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -704,5 +679,3 @@ Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS - ------------------------------------------------------------------------------- diff --git a/grbl/config.h b/grbl/config.h index 946e25a..e51b27c 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -1,8 +1,9 @@ /* config.h - compile time configuration - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2013-2015 Sungeun K. Jeon + Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2013 Sungeun K. Jeon -*/ // This file contains compile-time configurations for Grbl's internal system. For the most part, // users will not need to directly modify these, but they are here for specific needs, i.e. diff --git a/grbl/coolant_control.c b/grbl/coolant_control.c index f94f51a..4429dd4 100644 --- a/grbl/coolant_control.c +++ b/grbl/coolant_control.c @@ -1,6 +1,6 @@ /* coolant_control.c - coolant control methods - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon diff --git a/grbl/coolant_control.h b/grbl/coolant_control.h index f093cee..7694a78 100644 --- a/grbl/coolant_control.h +++ b/grbl/coolant_control.h @@ -1,6 +1,6 @@ /* coolant_control.h - spindle control methods - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon diff --git a/grbl/cpu_map.h b/grbl/cpu_map.h index 6c9134c..6469616 100644 --- a/grbl/cpu_map.h +++ b/grbl/cpu_map.h @@ -1,6 +1,6 @@ /* cpu_map.h - CPU and pin mapping configuration file - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon diff --git a/grbl/defaults.h b/grbl/defaults.h index 06dc0f7..f21b31e 100644 --- a/grbl/defaults.h +++ b/grbl/defaults.h @@ -1,6 +1,6 @@ /* defaults.h - defaults settings configuration file - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon diff --git a/grbl/eeprom.h b/grbl/eeprom.h index 0743425..c9718a2 100644 --- a/grbl/eeprom.h +++ b/grbl/eeprom.h @@ -2,28 +2,20 @@ eeprom.h - EEPROM methods Part of Grbl - The MIT License (MIT) - - GRBL(tm) - Embedded CNC g-code interpreter and motion-controller Copyright (c) 2009-2011 Simen Svale Skogsrud - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + 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. - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. + 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. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. + You should have received a copy of the GNU General Public License + along with Grbl. If not, see . */ #ifndef eeprom_h diff --git a/grbl/gcode.c b/grbl/gcode.c index 4b215e0..b915e48 100644 --- a/grbl/gcode.c +++ b/grbl/gcode.c @@ -1,9 +1,10 @@ /* gcode.c - rs274/ngc parser. - Part of Grbl v0.9 + Part of Grbl + + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2012-2015 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 @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #include "grbl.h" diff --git a/grbl/gcode.h b/grbl/gcode.h index d1ee3d5..0b478d0 100644 --- a/grbl/gcode.h +++ b/grbl/gcode.h @@ -1,8 +1,9 @@ /* gcode.h - rs274/ngc parser. - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #ifndef gcode_h #define gcode_h diff --git a/grbl/grbl.h b/grbl/grbl.h index dc331bf..42e2fcf 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -1,6 +1,6 @@ /* grbl.h - main Grbl include file - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2015 Sungeun K. Jeon diff --git a/grbl/limits.c b/grbl/limits.c index 84374f3..57de228 100644 --- a/grbl/limits.c +++ b/grbl/limits.c @@ -1,9 +1,10 @@ /* limits.c - code pertaining to limit-switches and performing the homing cycle - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon - + Copyright (c) 2009-2011 Simen Svale Skogsrud + 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 @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2012 Sungeun K. Jeon -*/ #include "grbl.h" @@ -202,8 +197,9 @@ void limits_go_home(uint8_t cycle_mask) st_prep_buffer(); // Check and prep segment buffer. NOTE: Should take no longer than 200us. // Check only for user reset. No time to run protocol_execute_realtime() in this loop. - if (sys.rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_RESET)) { // Abort homing and alarm upon safety door. - if (sys.rt_exec_state & EXEC_SAFETY_DOOR) { mc_reset(); } + // Exit routines: User abort homing and alarm upon safety door or no limit switch found. + if (sys.rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_RESET | EXEC_CYCLE_STOP)) { + if (sys.rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_CYCLE_STOP)) { mc_reset(); } protocol_execute_realtime(); return; } diff --git a/grbl/limits.h b/grbl/limits.h index 4c96a5d..0a5084a 100644 --- a/grbl/limits.h +++ b/grbl/limits.h @@ -1,9 +1,10 @@ /* limits.h - code pertaining to limit-switches and performing the homing cycle - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon - + Copyright (c) 2009-2011 Simen Svale Skogsrud + 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 @@ -17,11 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud -*/ #ifndef limits_h #define limits_h diff --git a/grbl/main.c b/grbl/main.c index 080d224..ef63659 100644 --- a/grbl/main.c +++ b/grbl/main.c @@ -1,9 +1,10 @@ /* main.c - An embedded CNC Controller with rs274/ngc (g-code) support - Part of Grbl v0.9 + Part of Grbl + + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2012-2015 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 @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #include "grbl.h" diff --git a/grbl/motion_control.c b/grbl/motion_control.c index 2a34af6..bfd42d7 100644 --- a/grbl/motion_control.c +++ b/grbl/motion_control.c @@ -1,8 +1,10 @@ /* motion_control.c - high level interface for issuing motion commands - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud + Copyright (c) 2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,13 +19,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon - Copyright (c) 2011 Jens Geisler -*/ #include "grbl.h" @@ -361,7 +356,8 @@ void mc_reset() // the steppers enabled by avoiding the go_idle call altogether, unless the motion state is // violated, by which, all bets are off. if ((sys.state & (STATE_CYCLE | STATE_HOMING)) || (sys.suspend == SUSPEND_ENABLE_HOLD)) { - bit_true_atomic(sys.rt_exec_alarm, EXEC_ALARM_ABORT_CYCLE); + if (sys.state == STATE_HOMING) { bit_true_atomic(sys.rt_exec_alarm, EXEC_ALARM_HOMING_FAIL); } + else { bit_true_atomic(sys.rt_exec_alarm, EXEC_ALARM_ABORT_CYCLE); } st_go_idle(); // Force kill steppers. Position has likely been lost. } } diff --git a/grbl/motion_control.h b/grbl/motion_control.h index 1cd1b2e..584d231 100644 --- a/grbl/motion_control.h +++ b/grbl/motion_control.h @@ -1,8 +1,9 @@ /* motion_control.h - high level interface for issuing motion commands - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #ifndef motion_control_h #define motion_control_h diff --git a/grbl/nuts_bolts.c b/grbl/nuts_bolts.c index 7da9d7e..b33e230 100644 --- a/grbl/nuts_bolts.c +++ b/grbl/nuts_bolts.c @@ -1,8 +1,9 @@ /* nuts_bolts.c - Shared functions - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #include "grbl.h" diff --git a/grbl/nuts_bolts.h b/grbl/nuts_bolts.h index 5f11eb2..882d337 100644 --- a/grbl/nuts_bolts.h +++ b/grbl/nuts_bolts.h @@ -1,8 +1,9 @@ /* nuts_bolts.h - Header file for shared definitions, variables, and functions - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #ifndef nuts_bolts_h #define nuts_bolts_h diff --git a/grbl/planner.c b/grbl/planner.c index 0946ce1..dcf50ec 100644 --- a/grbl/planner.c +++ b/grbl/planner.c @@ -1,8 +1,10 @@ /* planner.c - buffers movement commands and manages the acceleration profile plan - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud + Copyright (c) 2011 Jens Geisler Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,13 +19,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon - Copyright (c) 2011 Jens Geisler -*/ #include "grbl.h" diff --git a/grbl/planner.h b/grbl/planner.h index 8209c02..02258dd 100644 --- a/grbl/planner.h +++ b/grbl/planner.h @@ -1,8 +1,9 @@ /* planner.h - buffers movement commands and manages the acceleration profile plan - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #ifndef planner_h #define planner_h diff --git a/grbl/print.c b/grbl/print.c index 35d1c1c..1dd8d7b 100644 --- a/grbl/print.c +++ b/grbl/print.c @@ -1,8 +1,9 @@ /* print.c - Functions for formatting output strings - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #include "grbl.h" diff --git a/grbl/print.h b/grbl/print.h index 7b2040f..658e892 100644 --- a/grbl/print.h +++ b/grbl/print.h @@ -1,8 +1,9 @@ /* print.h - Functions for formatting output strings - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #ifndef print_h #define print_h diff --git a/grbl/probe.c b/grbl/probe.c index 133d73b..3bba4df 100644 --- a/grbl/probe.c +++ b/grbl/probe.c @@ -1,6 +1,6 @@ /* probe.c - code pertaining to probing methods - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2014-2015 Sungeun K. Jeon diff --git a/grbl/probe.h b/grbl/probe.h index 1e8674d..81bd486 100644 --- a/grbl/probe.h +++ b/grbl/probe.h @@ -1,6 +1,6 @@ /* probe.h - code pertaining to probing methods - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2014-2015 Sungeun K. Jeon diff --git a/grbl/protocol.c b/grbl/protocol.c index e6abd4f..2b81f00 100644 --- a/grbl/protocol.c +++ b/grbl/protocol.c @@ -1,8 +1,9 @@ /* protocol.c - controls Grbl execution protocol and procedures - Part of Grbl v0.9 - - Copyright (c) 2012-2015 Sungeun K. Jeon + Part of Grbl + + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #include "grbl.h" @@ -198,6 +193,8 @@ void protocol_execute_realtime() report_alarm_message(ALARM_ABORT_CYCLE); } else if (rt_exec & EXEC_ALARM_PROBE_FAIL) { report_alarm_message(ALARM_PROBE_FAIL); + } else if (rt_exec & EXEC_ALARM_HOMING_FAIL) { + report_alarm_message(ALARM_HOMING_FAIL); } // Halt everything upon a critical event flag. Currently hard and soft limits flag this. if (rt_exec & EXEC_CRITICAL_EVENT) { diff --git a/grbl/protocol.h b/grbl/protocol.h index 6095bd7..3fc3780 100644 --- a/grbl/protocol.h +++ b/grbl/protocol.h @@ -1,8 +1,9 @@ /* protocol.h - controls Grbl execution protocol and procedures - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #ifndef protocol_h #define protocol_h diff --git a/grbl/report.c b/grbl/report.c index 6e86ca6..1a84a0c 100644 --- a/grbl/report.c +++ b/grbl/report.c @@ -1,6 +1,6 @@ /* report.c - reporting and messaging methods - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon @@ -98,6 +98,8 @@ void report_alarm_message(int8_t alarm_code) printPgmString(PSTR("Abort during cycle")); break; case ALARM_PROBE_FAIL: printPgmString(PSTR("Probe fail")); break; + case ALARM_HOMING_FAIL: + printPgmString(PSTR("Homing fail")); break; } printPgmString(PSTR("\r\n")); delay_ms(500); // Force delay to ensure message clears serial write buffer. diff --git a/grbl/report.h b/grbl/report.h index 60ab960..cfd0d8b 100644 --- a/grbl/report.h +++ b/grbl/report.h @@ -1,6 +1,6 @@ /* report.h - reporting and messaging methods - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon @@ -59,6 +59,7 @@ #define ALARM_SOFT_LIMIT_ERROR -2 #define ALARM_ABORT_CYCLE -3 #define ALARM_PROBE_FAIL -4 +#define ALARM_HOMING_FAIL -5 // Define Grbl feedback message codes. #define MESSAGE_CRITICAL_EVENT 1 diff --git a/grbl/serial.c b/grbl/serial.c index a327def..edfbecf 100644 --- a/grbl/serial.c +++ b/grbl/serial.c @@ -1,8 +1,9 @@ /* serial.c - Low level functions for sending and recieving bytes via the serial port - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #include "grbl.h" diff --git a/grbl/serial.h b/grbl/serial.h index 9c28afd..b48fd35 100644 --- a/grbl/serial.h +++ b/grbl/serial.h @@ -1,8 +1,9 @@ /* serial.c - Low level functions for sending and recieving bytes via the serial port - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #ifndef serial_h #define serial_h diff --git a/grbl/settings.c b/grbl/settings.c index cd1e63b..956cb02 100644 --- a/grbl/settings.c +++ b/grbl/settings.c @@ -1,8 +1,9 @@ /* settings.c - eeprom configuration handling - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #include "grbl.h" diff --git a/grbl/settings.h b/grbl/settings.h index 01acd69..5090824 100644 --- a/grbl/settings.h +++ b/grbl/settings.h @@ -1,8 +1,9 @@ /* settings.h - eeprom configuration handling - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #ifndef settings_h #define settings_h diff --git a/grbl/spindle_control.c b/grbl/spindle_control.c index abad6c2..f0724b4 100644 --- a/grbl/spindle_control.c +++ b/grbl/spindle_control.c @@ -1,8 +1,9 @@ /* spindle_control.c - spindle control methods - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2012 Sungeun K. Jeon -*/ #include "grbl.h" diff --git a/grbl/spindle_control.h b/grbl/spindle_control.h index 0c728da..1aec91c 100644 --- a/grbl/spindle_control.h +++ b/grbl/spindle_control.h @@ -1,8 +1,9 @@ /* spindle_control.h - spindle control methods - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,12 +17,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . -*/ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2012 Sungeun K. Jeon */ #ifndef spindle_control_h diff --git a/grbl/stepper.c b/grbl/stepper.c index fafb104..155b805 100644 --- a/grbl/stepper.c +++ b/grbl/stepper.c @@ -1,8 +1,9 @@ /* stepper.c - stepper motor driver: executes motion plans using stepper motors - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #include "grbl.h" diff --git a/grbl/stepper.h b/grbl/stepper.h index fe4d853..0745704 100644 --- a/grbl/stepper.h +++ b/grbl/stepper.h @@ -1,8 +1,9 @@ /* stepper.h - stepper motor driver: executes motion plans of planner.c using the stepper motors - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011 Sungeun K. Jeon -*/ #ifndef stepper_h #define stepper_h diff --git a/grbl/system.c b/grbl/system.c index 7a09162..2f3d100 100644 --- a/grbl/system.c +++ b/grbl/system.c @@ -1,6 +1,6 @@ /* system.c - Handles system level commands and real-time processes - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2014-2015 Sungeun K. Jeon diff --git a/grbl/system.h b/grbl/system.h index d6e190e..a74f029 100644 --- a/grbl/system.h +++ b/grbl/system.h @@ -1,6 +1,6 @@ /* system.h - Header for system level commands and real-time processes - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2014-2015 Sungeun K. Jeon @@ -45,6 +45,7 @@ #define EXEC_ALARM_SOFT_LIMIT bit(2) // bitmask 00000100 #define EXEC_ALARM_ABORT_CYCLE bit(3) // bitmask 00001000 #define EXEC_ALARM_PROBE_FAIL bit(4) // bitmask 00010000 +#define EXEC_ALARM_HOMING_FAIL bit(5) // bitmask 00100000 // Define system state bit map. The state variable primarily tracks the individual functions // of Grbl to manage each without overlapping. It is also used as a messaging flag for From d034dc21817059a0ec2e679207ebf532212932d9 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Sun, 15 Feb 2015 19:23:16 -0700 Subject: [PATCH 33/40] Improved homing limit search handling. - Instead of a single overall max travel for a search distance for the homing limit switches. The homing cycle now applies the max travel of each axis to the search target. Generally makes more sense this way and saved more than a 100bytes of flash too. --- README.md | 4 ++-- grbl/grbl.h | 2 +- grbl/limits.c | 22 +++++++--------------- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index e03cc0f..3e69e23 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,11 @@ It accepts standards-compliant g-code and has been tested with the output of sev Grbl includes full acceleration management with look ahead. That means the controller will look up to 18 motions into the future and plan its velocities ahead to deliver smooth acceleration and jerk-free cornering. -* [Licensing](https://github.com/grbl/grbl/wiki/Licensing): Grbl v0.9 is free software, released under the GPLv3 license. Obsolete versions of Grbl, v0.8 and prior, are released under the permissive MIT-license. This will ensure Grbl will always be an open-source project while making the code permissive for others. +* [Licensing](https://github.com/grbl/grbl/wiki/Licensing): Grbl is free software, released under the GPLv3 license. * For more information and help, check out our **[Wiki pages!](https://github.com/grbl/grbl/wiki)** If you find that the information is out-dated, please to help us keep it updated by editing it or notifying our community! Thanks! -* Lead Developer [_2011 - Current_]: Sonny Jeon, Ph.D. (USA) +* Lead Developer [_2011 - Current_]: Sungeun(Sonny) K. Jeon, Ph.D. (USA) aka @chamnit * Lead Developer [_2009 - 2011_]: Simen Svale Skogsrud (Norway). aka The Originator/Creator/Pioneer/Father of Grbl. diff --git a/grbl/grbl.h b/grbl/grbl.h index 42e2fcf..08e7dd7 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -23,7 +23,7 @@ // Grbl versioning system #define GRBL_VERSION "0.9h" -#define GRBL_VERSION_BUILD "20150210" +#define GRBL_VERSION_BUILD "20150215" // Define standard libraries used by Grbl. #include diff --git a/grbl/limits.c b/grbl/limits.c index 57de228..6f00b06 100644 --- a/grbl/limits.c +++ b/grbl/limits.c @@ -124,7 +124,7 @@ void limits_go_home(uint8_t cycle_mask) float target[N_AXIS]; uint8_t limit_pin[N_AXIS], step_pin[N_AXIS]; - float max_travel = 0.0; + float max_travel; for (idx=0; idx settings.max_travel[idx]) { max_travel = settings.max_travel[idx]; } } - max_travel *= -HOMING_AXIS_SEARCH_SCALAR; // Ensure homing switches engaged by over-estimating max travel. plan_reset(); // Reset planner buffer to zero planner current position and to clear previous motions. plan_sync_position(); // Sync planner position to current machine position. @@ -156,15 +151,12 @@ void limits_go_home(uint8_t cycle_mask) // Set target location for active axes and setup computation for homing rate. if (bit_istrue(cycle_mask,bit(idx))) { n_active_axis++; - if (approach) { - // Set target direction based on cycle mask - if (bit_istrue(settings.homing_dir_mask,bit(idx))) { target[idx] -= max_travel; } - else { target[idx] += max_travel; } - } else { - // Set target direction based on cycle mask - if (bit_istrue(settings.homing_dir_mask,bit(idx))) { target[idx] += max_travel; } - else { target[idx] -= max_travel; } - } + // Set target based on max_travel setting. Ensure homing switches engaged with search scalar. + // NOTE: settings.max_travel[] is stored as a negative value. + max_travel = (-HOMING_AXIS_SEARCH_SCALAR)*settings.max_travel[idx]; + if (bit_istrue(settings.homing_dir_mask,bit(idx))) { max_travel = -max_travel; } + if (!approach) { max_travel = -max_travel; } + target[idx] += max_travel; } // Apply axislock to the step port pins active in this cycle. From c7db1c4546665174adad0664b73d6792a2a6dfb1 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Mon, 23 Feb 2015 18:45:26 -0700 Subject: [PATCH 34/40] New configuration options. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - New configuration option at compile-time: - Force alarm upon power-up or hard reset. When homing is enabled, this is already the default behavior. This simply forces this all of the time. - GUI reporting mode. Removes most human-readable strings that GUIs don’t need. This saves nearly 2KB in flash space that can be used for other features. - Hard limit force state check: In the hard limit pin change ISR, Grbl by default sets the hard limit alarm upon any pin change to guarantee the alarm is set. If this option is set, it’ll check the state within the ISR, but can’t guarantee the pin will be read correctly if the switch is bouncing. This option makes hard limit behavior a little less annoying if you have a good buffered switch circuit that removes bouncing and electronic noise. - Software debounce bug fix. It was reading the pin incorrectly for the setting. - Re-factored some of the ‘$’ settings code. --- grbl/config.h | 34 ++++++- grbl/grbl.h | 4 +- grbl/limits.c | 20 +++-- grbl/main.c | 5 ++ grbl/report.c | 239 +++++++++++++++++++++++++++++--------------------- grbl/system.c | 97 ++++++++++---------- 6 files changed, 240 insertions(+), 159 deletions(-) diff --git a/grbl/config.h b/grbl/config.h index e51b27c..297742e 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -106,8 +106,8 @@ // this feature. Since the two switches are sharing a single pin, there is no way for Grbl to tell // which one is enabled. This option only effects homing, where if a limit is engaged, Grbl will // alarm out and force the user to manually disengage the limit switch. Otherwise, if you have one -// limit switch for each axis, don't enable this option. By keeping it disabled, you can homing while -// on the limit switch and not have to move the machine off of it. +// limit switch for each axis, don't enable this option. By keeping it disabled, you can perform a +// homing cycle while on the limit switch and not have to move the machine off of it. // #define LIMITS_TWO_SWITCHES_ON_AXES // Allows GRBL to track and report gcode line numbers. Enabling this means that the planning buffer @@ -161,9 +161,22 @@ // with little to no benefit during normal operation. // #define REPORT_INPUT_PIN_STATES // Default disabled. Uncomment to enable. +// When Grbl powers-cycles or is hard reset with the Arduino reset button, Grbl boots up with no ALARM +// by default. This is to make it as simple as possible for new users to start using Grbl. When homing +// is enabled and a user has installed limit switches, Grbl will boot up in an ALARM state to indicate +// Grbl doesn't know its position and to force the user to home before proceeding. This option forces +// Grbl to always initialize into an ALARM state regardless of homing or not. This option is more for +// OEMs and LinuxCNC users that would like this power-cycle behavior. +// #define FORCE_INITIALIZATION_ALARM // Default disabled. Uncomment to enable. + // --------------------------------------------------------------------------------------- // ADVANCED CONFIGURATION OPTIONS: +// Enables minimal reporting feedback mode for GUIs, where human-readable strings are not as important. +// This saves nearly 2KB of flash space and may allow enough space to install other/future features. +// NOTE: This feature is new and experimental. Make sure the GUI you are using supports this mode. +#define REPORT_GUI_MODE // Default disabled. Uncomment to enable. + // The temporal resolution of the acceleration management subsystem. A higher number gives smoother // acceleration, particularly noticeable on machines that run at very high feedrates, but may negatively // impact performance. The correct value for this parameter is machine dependent, so it's advised to @@ -180,8 +193,10 @@ // step smoothing. See stepper.c for more details on the AMASS system works. #define ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING // Default enabled. Comment to disable. -// Sets the maximum step rate allowed to be written as a Grbl setting. This value is strictly limited -// by the CPU speed and will change if something other than an AVR running at 16MHz is used. +// Sets the maximum step rate allowed to be written as a Grbl setting. This option enables an error +// check in the settings module to prevent settings values that will exceed this limitation. The maximum +// step rate is strictly limited by the CPU speed and will change if something other than an AVR running +// at 16MHz is used. // NOTE: For now disabled, will enable if flash space permits. // #define MAX_STEP_RATE_HZ 30000 // Hz @@ -318,6 +333,17 @@ // work well and are cheap to find) and wire in a low-pass circuit into each limit pin. // #define ENABLE_SOFTWARE_DEBOUNCE // Default disabled. Uncomment to enable. +// Force Grbl to check the state of the hard limit switches when the processor detects a pin +// change inside the hard limit ISR routine. By default, Grbl will trigger the hard limits +// alarm upon any pin change, since bouncing switches can cause a state check like this to +// misread the pin. When hard limits are triggers, this should be 100% reliable, which is the +// reason that this option is disabled by default. Only if your system/electronics can guarantee +// the pins don't bounce, we recommend enabling this option. If so, this will help prevent +// triggering a hard limit when the machine disengages from the switch. +// NOTE: This option has no effect if SOFTWARE_DEBOUNCE is enabled. +// #define HARD_LIMIT_FORCE_STATE_CHECK // Default disabled. Uncomment to enable. + + // --------------------------------------------------------------------------------------- // TODO: Install compile-time option to send numeric status codes rather than strings. diff --git a/grbl/grbl.h b/grbl/grbl.h index 08e7dd7..ff92269 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -22,8 +22,8 @@ #define grbl_h // Grbl versioning system -#define GRBL_VERSION "0.9h" -#define GRBL_VERSION_BUILD "20150215" +#define GRBL_VERSION "0.9i" +#define GRBL_VERSION_BUILD "20150223" // Define standard libraries used by Grbl. #include diff --git a/grbl/limits.c b/grbl/limits.c index 6f00b06..75b9f82 100644 --- a/grbl/limits.c +++ b/grbl/limits.c @@ -79,8 +79,18 @@ void limits_disable() // limit setting if their limits are constantly triggering after a reset and move their axes. if (sys.state != STATE_ALARM) { if (!(sys.rt_exec_alarm)) { - mc_reset(); // Initiate system kill. - bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event + #ifdef HARD_LIMIT_FORCE_STATE_CHECK + uint8_t bits = (LIMIT_PIN & LIMIT_MASK); + // Check limit pin state. + if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { bits ^= LIMIT_MASK; } + if (bits) { + mc_reset(); // Initiate system kill. + bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event + } + #else + mc_reset(); // Initiate system kill. + bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event + #endif } } } @@ -92,10 +102,10 @@ void limits_disable() WDTCSR &= ~(1< 30kHz")); break; + #ifdef REPORT_GUI_MODE + print_uint8_base10(status_code); + #else + switch(status_code) { + case STATUS_EXPECTED_COMMAND_LETTER: + printPgmString(PSTR("Expected command letter")); break; + case STATUS_BAD_NUMBER_FORMAT: + printPgmString(PSTR("Bad number format")); break; + case STATUS_INVALID_STATEMENT: + printPgmString(PSTR("Invalid statement")); break; + case STATUS_NEGATIVE_VALUE: + printPgmString(PSTR("Value < 0")); break; + case STATUS_SETTING_DISABLED: + printPgmString(PSTR("Setting disabled")); break; + case STATUS_SETTING_STEP_PULSE_MIN: + printPgmString(PSTR("Value < 3 usec")); break; + case STATUS_SETTING_READ_FAIL: + printPgmString(PSTR("EEPROM read fail. Using defaults")); break; + case STATUS_IDLE_ERROR: + printPgmString(PSTR("Not idle")); break; + case STATUS_ALARM_LOCK: + printPgmString(PSTR("Alarm lock")); break; + case STATUS_SOFT_LIMIT_ERROR: + printPgmString(PSTR("Homing not enabled")); break; + case STATUS_OVERFLOW: + printPgmString(PSTR("Line overflow")); break; + // case STATUS_MAX_STEP_RATE_EXCEEDED: + // printPgmString(PSTR("Step rate > 30kHz")); break; - // Common g-code parser errors. - case STATUS_GCODE_MODAL_GROUP_VIOLATION: - printPgmString(PSTR("Modal group violation")); break; - case STATUS_GCODE_UNSUPPORTED_COMMAND: - printPgmString(PSTR("Unsupported command")); break; - case STATUS_GCODE_UNDEFINED_FEED_RATE: - printPgmString(PSTR("Undefined feed rate")); break; - default: - // Remaining g-code parser errors with error codes - printPgmString(PSTR("Invalid gcode ID:")); - print_uint8_base10(status_code); // Print error code for user reference - } + // Common g-code parser errors. + case STATUS_GCODE_MODAL_GROUP_VIOLATION: + printPgmString(PSTR("Modal group violation")); break; + case STATUS_GCODE_UNSUPPORTED_COMMAND: + printPgmString(PSTR("Unsupported command")); break; + case STATUS_GCODE_UNDEFINED_FEED_RATE: + printPgmString(PSTR("Undefined feed rate")); break; + default: + // Remaining g-code parser errors with error codes + printPgmString(PSTR("Invalid gcode ID:")); + print_uint8_base10(status_code); // Print error code for user reference + } + #endif printPgmString(PSTR("\r\n")); } } @@ -89,18 +93,22 @@ void report_status_message(uint8_t status_code) void report_alarm_message(int8_t alarm_code) { printPgmString(PSTR("ALARM: ")); - switch (alarm_code) { - case ALARM_HARD_LIMIT_ERROR: - printPgmString(PSTR("Hard limit")); break; - case ALARM_SOFT_LIMIT_ERROR: - printPgmString(PSTR("Soft limit")); break; - case ALARM_ABORT_CYCLE: - printPgmString(PSTR("Abort during cycle")); break; - case ALARM_PROBE_FAIL: - printPgmString(PSTR("Probe fail")); break; - case ALARM_HOMING_FAIL: - printPgmString(PSTR("Homing fail")); break; - } + #ifdef REPORT_GUI_MODE + print_uint8_base10(alarm_code); + #else + switch (alarm_code) { + case ALARM_HARD_LIMIT_ERROR: + printPgmString(PSTR("Hard limit")); break; + case ALARM_SOFT_LIMIT_ERROR: + printPgmString(PSTR("Soft limit")); break; + case ALARM_ABORT_CYCLE: + printPgmString(PSTR("Abort during cycle")); break; + case ALARM_PROBE_FAIL: + printPgmString(PSTR("Probe fail")); break; + case ALARM_HOMING_FAIL: + printPgmString(PSTR("Homing fail")); break; + } + #endif printPgmString(PSTR("\r\n")); delay_ms(500); // Force delay to ensure message clears serial write buffer. } @@ -140,20 +148,22 @@ void report_init_message() // Grbl help message void report_grbl_help() { - printPgmString(PSTR("$$ (view Grbl settings)\r\n" - "$# (view # parameters)\r\n" - "$G (view parser state)\r\n" - "$I (view build info)\r\n" - "$N (view startup blocks)\r\n" - "$x=value (save Grbl setting)\r\n" - "$Nx=line (save startup block)\r\n" - "$C (check gcode mode)\r\n" - "$X (kill alarm lock)\r\n" - "$H (run homing cycle)\r\n" - "~ (cycle start)\r\n" - "! (feed hold)\r\n" - "? (current status)\r\n" - "ctrl-x (reset Grbl)\r\n")); + #ifndef REPORT_GUI_MODE + printPgmString(PSTR("$$ (view Grbl settings)\r\n" + "$# (view # parameters)\r\n" + "$G (view parser state)\r\n" + "$I (view build info)\r\n" + "$N (view startup blocks)\r\n" + "$x=value (save Grbl setting)\r\n" + "$Nx=line (save startup block)\r\n" + "$C (check gcode mode)\r\n" + "$X (kill alarm lock)\r\n" + "$H (run homing cycle)\r\n" + "~ (cycle start)\r\n" + "! (feed hold)\r\n" + "? (current status)\r\n" + "ctrl-x (reset Grbl)\r\n")); + #endif } @@ -161,31 +171,54 @@ void report_grbl_help() { // NOTE: The numbering scheme here must correlate to storing in settings.c void report_grbl_settings() { // Print Grbl settings. - printPgmString(PSTR("$0=")); print_uint8_base10(settings.pulse_microseconds); - printPgmString(PSTR(" (step pulse, usec)\r\n$1=")); print_uint8_base10(settings.stepper_idle_lock_time); - printPgmString(PSTR(" (step idle delay, msec)\r\n$2=")); print_uint8_base10(settings.step_invert_mask); - printPgmString(PSTR(" (step port invert mask:")); print_uint8_base2(settings.step_invert_mask); - printPgmString(PSTR(")\r\n$3=")); print_uint8_base10(settings.dir_invert_mask); - printPgmString(PSTR(" (dir port invert mask:")); print_uint8_base2(settings.dir_invert_mask); - printPgmString(PSTR(")\r\n$4=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)); - printPgmString(PSTR(" (step enable invert, bool)\r\n$5=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)); - printPgmString(PSTR(" (limit pins invert, bool)\r\n$6=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_PROBE_PIN)); - printPgmString(PSTR(" (probe pin invert, bool)\r\n$10=")); print_uint8_base10(settings.status_report_mask); - printPgmString(PSTR(" (status report mask:")); print_uint8_base2(settings.status_report_mask); - printPgmString(PSTR(")\r\n$11=")); printFloat_SettingValue(settings.junction_deviation); - printPgmString(PSTR(" (junction deviation, mm)\r\n$12=")); printFloat_SettingValue(settings.arc_tolerance); - printPgmString(PSTR(" (arc tolerance, mm)\r\n$13=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)); - printPgmString(PSTR(" (report inches, bool)\r\n$20=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)); - printPgmString(PSTR(" (soft limits, bool)\r\n$21=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)); - printPgmString(PSTR(" (hard limits, bool)\r\n$22=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)); - printPgmString(PSTR(" (homing cycle, bool)\r\n$23=")); print_uint8_base10(settings.homing_dir_mask); - printPgmString(PSTR(" (homing dir invert mask:")); print_uint8_base2(settings.homing_dir_mask); - printPgmString(PSTR(")\r\n$24=")); printFloat_SettingValue(settings.homing_feed_rate); - printPgmString(PSTR(" (homing feed, mm/min)\r\n$25=")); printFloat_SettingValue(settings.homing_seek_rate); - printPgmString(PSTR(" (homing seek, mm/min)\r\n$26=")); print_uint8_base10(settings.homing_debounce_delay); - printPgmString(PSTR(" (homing debounce, msec)\r\n$27=")); printFloat_SettingValue(settings.homing_pulloff); - printPgmString(PSTR(" (homing pull-off, mm)\r\n")); - + #ifdef REPORT_GUI_MODE + printPgmString(PSTR("$0=")); print_uint8_base10(settings.pulse_microseconds); + printPgmString(PSTR("\r\n$1=")); print_uint8_base10(settings.stepper_idle_lock_time); + printPgmString(PSTR("\r\n$2=")); print_uint8_base10(settings.step_invert_mask); + printPgmString(PSTR("\r\n$3=")); print_uint8_base10(settings.dir_invert_mask); + printPgmString(PSTR("\r\n$4=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)); + printPgmString(PSTR("\r\n$5=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)); + printPgmString(PSTR("\r\n$6=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_PROBE_PIN)); + printPgmString(PSTR("\r\n$10=")); print_uint8_base10(settings.status_report_mask); + printPgmString(PSTR("\r\n$11=")); printFloat_SettingValue(settings.junction_deviation); + printPgmString(PSTR("\r\n$12=")); printFloat_SettingValue(settings.arc_tolerance); + printPgmString(PSTR("\r\n$13=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)); + printPgmString(PSTR("\r\n$20=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)); + printPgmString(PSTR("\r\n$21=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)); + printPgmString(PSTR("\r\n$22=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)); + printPgmString(PSTR("\r\n$23=")); print_uint8_base10(settings.homing_dir_mask); + printPgmString(PSTR("\r\n$24=")); printFloat_SettingValue(settings.homing_feed_rate); + printPgmString(PSTR("\r\n$25=")); printFloat_SettingValue(settings.homing_seek_rate); + printPgmString(PSTR("\r\n$26=")); print_uint8_base10(settings.homing_debounce_delay); + printPgmString(PSTR("\r\n$27=")); printFloat_SettingValue(settings.homing_pulloff); + printPgmString(PSTR("\r\n")); + #else + printPgmString(PSTR("$0=")); print_uint8_base10(settings.pulse_microseconds); + printPgmString(PSTR(" (step pulse, usec)\r\n$1=")); print_uint8_base10(settings.stepper_idle_lock_time); + printPgmString(PSTR(" (step idle delay, msec)\r\n$2=")); print_uint8_base10(settings.step_invert_mask); + printPgmString(PSTR(" (step port invert mask:")); print_uint8_base2(settings.step_invert_mask); + printPgmString(PSTR(")\r\n$3=")); print_uint8_base10(settings.dir_invert_mask); + printPgmString(PSTR(" (dir port invert mask:")); print_uint8_base2(settings.dir_invert_mask); + printPgmString(PSTR(")\r\n$4=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)); + printPgmString(PSTR(" (step enable invert, bool)\r\n$5=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)); + printPgmString(PSTR(" (limit pins invert, bool)\r\n$6=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_PROBE_PIN)); + printPgmString(PSTR(" (probe pin invert, bool)\r\n$10=")); print_uint8_base10(settings.status_report_mask); + printPgmString(PSTR(" (status report mask:")); print_uint8_base2(settings.status_report_mask); + printPgmString(PSTR(")\r\n$11=")); printFloat_SettingValue(settings.junction_deviation); + printPgmString(PSTR(" (junction deviation, mm)\r\n$12=")); printFloat_SettingValue(settings.arc_tolerance); + printPgmString(PSTR(" (arc tolerance, mm)\r\n$13=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)); + printPgmString(PSTR(" (report inches, bool)\r\n$20=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)); + printPgmString(PSTR(" (soft limits, bool)\r\n$21=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)); + printPgmString(PSTR(" (hard limits, bool)\r\n$22=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)); + printPgmString(PSTR(" (homing cycle, bool)\r\n$23=")); print_uint8_base10(settings.homing_dir_mask); + printPgmString(PSTR(" (homing dir invert mask:")); print_uint8_base2(settings.homing_dir_mask); + printPgmString(PSTR(")\r\n$24=")); printFloat_SettingValue(settings.homing_feed_rate); + printPgmString(PSTR(" (homing feed, mm/min)\r\n$25=")); printFloat_SettingValue(settings.homing_seek_rate); + printPgmString(PSTR(" (homing seek, mm/min)\r\n$26=")); print_uint8_base10(settings.homing_debounce_delay); + printPgmString(PSTR(" (homing debounce, msec)\r\n$27=")); printFloat_SettingValue(settings.homing_pulloff); + printPgmString(PSTR(" (homing pull-off, mm)\r\n")); + #endif + // Print axis settings uint8_t idx, set_idx; uint8_t val = AXIS_SETTINGS_START_VAL; @@ -200,19 +233,23 @@ void report_grbl_settings() { case 2: printFloat_SettingValue(settings.acceleration[idx]/(60*60)); break; case 3: printFloat_SettingValue(-settings.max_travel[idx]); break; } - printPgmString(PSTR(" (")); - switch (idx) { - case X_AXIS: printPgmString(PSTR("x")); break; - case Y_AXIS: printPgmString(PSTR("y")); break; - case Z_AXIS: printPgmString(PSTR("z")); break; - } - switch (set_idx) { - case 0: printPgmString(PSTR(", step/mm")); break; - case 1: printPgmString(PSTR(" max rate, mm/min")); break; - case 2: printPgmString(PSTR(" accel, mm/sec^2")); break; - case 3: printPgmString(PSTR(" max travel, mm")); break; - } - printPgmString(PSTR(")\r\n")); + #ifdef REPORT_GUI_MODE + printPgmString(PSTR("\r\n")); + #else + printPgmString(PSTR(" (")); + switch (idx) { + case X_AXIS: printPgmString(PSTR("x")); break; + case Y_AXIS: printPgmString(PSTR("y")); break; + case Z_AXIS: printPgmString(PSTR("z")); break; + } + switch (set_idx) { + case 0: printPgmString(PSTR(", step/mm")); break; + case 1: printPgmString(PSTR(" max rate, mm/min")); break; + case 2: printPgmString(PSTR(" accel, mm/sec^2")); break; + case 3: printPgmString(PSTR(" max travel, mm")); break; + } + printPgmString(PSTR(")\r\n")); + #endif } val += AXIS_SETTINGS_INCREMENT; } diff --git a/grbl/system.c b/grbl/system.c index 2f3d100..a31c5fe 100644 --- a/grbl/system.c +++ b/grbl/system.c @@ -109,54 +109,57 @@ uint8_t system_execute_line(char *line) float parameter, value; switch( line[char_counter] ) { case 0 : report_grbl_help(); break; - case '$' : // Prints Grbl settings - if ( line[++char_counter] != 0 ) { return(STATUS_INVALID_STATEMENT); } - if ( sys.state & (STATE_CYCLE | STATE_HOLD) ) { return(STATUS_IDLE_ERROR); } // Block during cycle. Takes too long to print. - else { report_grbl_settings(); } - break; - case 'G' : // Prints gcode parser state - // TODO: Move this to realtime commands for GUIs to request this data during suspend-state. - if ( line[++char_counter] != 0 ) { return(STATUS_INVALID_STATEMENT); } - else { report_gcode_modes(); } - break; - case 'C' : // Set check g-code mode [IDLE/CHECK] - if ( line[++char_counter] != 0 ) { return(STATUS_INVALID_STATEMENT); } - // Perform reset when toggling off. Check g-code mode should only work if Grbl - // is idle and ready, regardless of alarm locks. This is mainly to keep things - // simple and consistent. - if ( sys.state == STATE_CHECK_MODE ) { - mc_reset(); - report_feedback_message(MESSAGE_DISABLED); - } else { - if (sys.state) { return(STATUS_IDLE_ERROR); } // Requires no alarm mode. - sys.state = STATE_CHECK_MODE; - report_feedback_message(MESSAGE_ENABLED); + case '$': case 'G': case 'C': case 'X': + if ( line[(char_counter+1)] != 0 ) { return(STATUS_INVALID_STATEMENT); } + switch( line[char_counter] ) { + case '$' : // Prints Grbl settings + if ( sys.state & (STATE_CYCLE | STATE_HOLD) ) { return(STATUS_IDLE_ERROR); } // Block during cycle. Takes too long to print. + else { report_grbl_settings(); } + break; + case 'G' : // Prints gcode parser state + // TODO: Move this to realtime commands for GUIs to request this data during suspend-state. + report_gcode_modes(); + break; + case 'C' : // Set check g-code mode [IDLE/CHECK] + // Perform reset when toggling off. Check g-code mode should only work if Grbl + // is idle and ready, regardless of alarm locks. This is mainly to keep things + // simple and consistent. + if ( sys.state == STATE_CHECK_MODE ) { + mc_reset(); + report_feedback_message(MESSAGE_DISABLED); + } else { + if (sys.state) { return(STATUS_IDLE_ERROR); } // Requires no alarm mode. + sys.state = STATE_CHECK_MODE; + report_feedback_message(MESSAGE_ENABLED); + } + break; + case 'X' : // Disable alarm lock [ALARM] + if (sys.state == STATE_ALARM) { + report_feedback_message(MESSAGE_ALARM_UNLOCK); + sys.state = STATE_IDLE; + // Don't run startup script. Prevents stored moves in startup from causing accidents. + if (system_check_safety_door_ajar()) { // Check safety door switch before returning. + bit_true(sys.rt_exec_state, EXEC_SAFETY_DOOR); + protocol_execute_realtime(); // Enter safety door mode. + } + } // Otherwise, no effect. + break; + // case 'J' : break; // Jogging methods + // TODO: Here jogging can be placed for execution as a seperate subprogram. It does not need to be + // susceptible to other realtime commands except for e-stop. The jogging function is intended to + // be a basic toggle on/off with controlled acceleration and deceleration to prevent skipped + // steps. The user would supply the desired feedrate, axis to move, and direction. Toggle on would + // start motion and toggle off would initiate a deceleration to stop. One could 'feather' the + // motion by repeatedly toggling to slow the motion to the desired location. Location data would + // need to be updated real-time and supplied to the user through status queries. + // More controlled exact motions can be taken care of by inputting G0 or G1 commands, which are + // handled by the planner. It would be possible for the jog subprogram to insert blocks into the + // block buffer without having the planner plan them. It would need to manage de/ac-celerations + // on its own carefully. This approach could be effective and possibly size/memory efficient. +// } +// break; } - break; - case 'X' : // Disable alarm lock [ALARM] - if ( line[++char_counter] != 0 ) { return(STATUS_INVALID_STATEMENT); } - if (sys.state == STATE_ALARM) { - report_feedback_message(MESSAGE_ALARM_UNLOCK); - sys.state = STATE_IDLE; - // Don't run startup script. Prevents stored moves in startup from causing accidents. - if (system_check_safety_door_ajar()) { // Check safety door switch before returning. - bit_true(sys.rt_exec_state, EXEC_SAFETY_DOOR); - protocol_execute_realtime(); // Enter safety door mode. - } - } // Otherwise, no effect. - break; -// case 'J' : break; // Jogging methods - // TODO: Here jogging can be placed for execution as a seperate subprogram. It does not need to be - // susceptible to other realtime commands except for e-stop. The jogging function is intended to - // be a basic toggle on/off with controlled acceleration and deceleration to prevent skipped - // steps. The user would supply the desired feedrate, axis to move, and direction. Toggle on would - // start motion and toggle off would initiate a deceleration to stop. One could 'feather' the - // motion by repeatedly toggling to slow the motion to the desired location. Location data would - // need to be updated real-time and supplied to the user through status queries. - // More controlled exact motions can be taken care of by inputting G0 or G1 commands, which are - // handled by the planner. It would be possible for the jog subprogram to insert blocks into the - // block buffer without having the planner plan them. It would need to manage de/ac-celerations - // on its own carefully. This approach could be effective and possibly size/memory efficient. + break; default : // Block any system command that requires the state as IDLE/ALARM. (i.e. EEPROM, homing) if ( !(sys.state == STATE_IDLE || sys.state == STATE_ALARM) ) { return(STATUS_IDLE_ERROR); } From d4ae8f94aff41a8b8a70e7bf0ee1387334fa354d Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Mon, 23 Feb 2015 18:50:32 -0700 Subject: [PATCH 35/40] Fixed config.h to Grbl release defaults. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - REPORT_GUI_MODE was accidentally enabled, when it shouldn’t have. --- grbl/config.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/grbl/config.h b/grbl/config.h index 297742e..cde5065 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -174,8 +174,9 @@ // Enables minimal reporting feedback mode for GUIs, where human-readable strings are not as important. // This saves nearly 2KB of flash space and may allow enough space to install other/future features. +// GUIs will need to install a look-up table for the error-codes that Grbl sends back in their place. // NOTE: This feature is new and experimental. Make sure the GUI you are using supports this mode. -#define REPORT_GUI_MODE // Default disabled. Uncomment to enable. +// #define REPORT_GUI_MODE // Default disabled. Uncomment to enable. // The temporal resolution of the acceleration management subsystem. A higher number gives smoother // acceleration, particularly noticeable on machines that run at very high feedrates, but may negatively @@ -226,7 +227,7 @@ // enable pin will output 5V for maximum RPM with 256 intermediate levels and 0V when disabled. // NOTE: IMPORTANT for Arduino Unos! When enabled, the Z-limit pin D11 and spindle enable pin D12 switch! // The hardware PWM output on pin D11 is required for variable spindle output voltages. -#define VARIABLE_SPINDLE // Default disabled. Uncomment to enable. +#define VARIABLE_SPINDLE // Default enabled. Comment to disable. // Used by the variable spindle output only. These parameters set the maximum and minimum spindle speed // "S" g-code values to correspond to the maximum and minimum pin voltages. There are 256 discrete and From 85b0c7a8b48e68fe0c4a5e8b2d8cb24a0789a231 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Wed, 25 Feb 2015 08:29:56 -0700 Subject: [PATCH 36/40] G91.1 support. Fixed a config.h option. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - G91.1 support added. This g-code sets the arc IJK distance mode to incremental, which is the default already. This simply helps reduce parsing errors with certain CAM programs that output this command. - Max step rate checks weren’t being compiled in if the option was enabled. Fixed now. - Alarm codes were not displaying correctly when GUI reporting mode was enabled. Due to unsigned int problem. Changed codes to positive values since they aren’t shared with other codes. --- README.md | 1 + grbl/gcode.c | 13 ++++++++++--- grbl/gcode.h | 20 ++++++++++++-------- grbl/report.c | 9 +++++---- grbl/report.h | 14 +++++++------- grbl/settings.c | 8 ++++++-- 6 files changed, 41 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 3e69e23..962d932 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ List of Supported G-Codes in Grbl v0.9 - Feed Rate Modes: G93, G94 - Unit Modes: G20, G21 - Distance Modes: G90, G91 + - Arc IJK Distance Modes: G91.1 - Plane Select Modes: G17, G18, G19 - Tool Length Offset Modes: G43.1, G49 - Cutter Compensation Modes: G40 diff --git a/grbl/gcode.c b/grbl/gcode.c index b915e48..37f9ff9 100644 --- a/grbl/gcode.c +++ b/grbl/gcode.c @@ -213,9 +213,16 @@ uint8_t gc_execute_line(char *line) } break; case 90: case 91: - word_bit = MODAL_GROUP_G3; - if (int_value == 90) { gc_block.modal.distance = DISTANCE_MODE_ABSOLUTE; } // G90 - else { gc_block.modal.distance = DISTANCE_MODE_INCREMENTAL; } // G91 + if (mantissa == 0) { + word_bit = MODAL_GROUP_G3; + if (int_value == 90) { gc_block.modal.distance = DISTANCE_MODE_ABSOLUTE; } // G90 + else { gc_block.modal.distance = DISTANCE_MODE_INCREMENTAL; } // G91 + } else { + word_bit = MODAL_GROUP_G4; + if (mantissa != 10) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [G90.1 not supported] + mantissa = 0; // Set to zero to indicate valid non-integer G command. + // Otherwise, arc IJK incremental mode is default. G91.1 does nothing. + } break; case 93: case 94: word_bit = MODAL_GROUP_G5; diff --git a/grbl/gcode.h b/grbl/gcode.h index 0b478d0..46df351 100644 --- a/grbl/gcode.h +++ b/grbl/gcode.h @@ -33,15 +33,16 @@ #define MODAL_GROUP_G1 1 // [G0,G1,G2,G3,G38.2,G80] Motion #define MODAL_GROUP_G2 2 // [G17,G18,G19] Plane selection #define MODAL_GROUP_G3 3 // [G90,G91] Distance mode -#define MODAL_GROUP_G5 4 // [G93,G94] Feed rate mode -#define MODAL_GROUP_G6 5 // [G20,G21] Units -#define MODAL_GROUP_G7 6 // [G40] Cutter radius compensation mode. G41/42 NOT SUPPORTED. -#define MODAL_GROUP_G8 7 // [G43,G43.1,G49] Tool length offset -#define MODAL_GROUP_G12 8 // [G54,G55,G56,G57,G58,G59] Coordinate system selection +#define MODAL_GROUP_G4 4 // [G90.1,G91.1] Arc IJK distance mode +#define MODAL_GROUP_G5 5 // [G93,G94] Feed rate mode +#define MODAL_GROUP_G6 6 // [G20,G21] Units +#define MODAL_GROUP_G7 7 // [G40] Cutter radius compensation mode. G41/42 NOT SUPPORTED. +#define MODAL_GROUP_G8 8 // [G43,G43.1,G49] Tool length offset +#define MODAL_GROUP_G12 9 // [G54,G55,G56,G57,G58,G59] Coordinate system selection -#define MODAL_GROUP_M4 9 // [M0,M1,M2,M30] Stopping -#define MODAL_GROUP_M7 10 // [M3,M4,M5] Spindle turning -#define MODAL_GROUP_M8 11 // [M7,M8,M9] Coolant control +#define MODAL_GROUP_M4 10 // [M0,M1,M2,M30] Stopping +#define MODAL_GROUP_M7 11 // [M3,M4,M5] Spindle turning +#define MODAL_GROUP_M8 12 // [M7,M8,M9] Coolant control #define OTHER_INPUT_F 12 #define OTHER_INPUT_S 13 @@ -82,6 +83,9 @@ #define DISTANCE_MODE_ABSOLUTE 0 // G90 (Default: Must be zero) #define DISTANCE_MODE_INCREMENTAL 1 // G91 +// Modal Group G4: Arc IJK distance mode +#define DISTANCE_ARC_MODE_INCREMENTAL 0 // G91.1 (Default: Must be zero) + // Modal Group M4: Program flow #define PROGRAM_FLOW_RUNNING 0 // (Default: Must be zero) #define PROGRAM_FLOW_PAUSED 1 // M0, M1 diff --git a/grbl/report.c b/grbl/report.c index eae6995..9460f6a 100644 --- a/grbl/report.c +++ b/grbl/report.c @@ -68,10 +68,11 @@ void report_status_message(uint8_t status_code) case STATUS_SOFT_LIMIT_ERROR: printPgmString(PSTR("Homing not enabled")); break; case STATUS_OVERFLOW: - printPgmString(PSTR("Line overflow")); break; - // case STATUS_MAX_STEP_RATE_EXCEEDED: - // printPgmString(PSTR("Step rate > 30kHz")); break; - + printPgmString(PSTR("Line overflow")); break; + #ifdef MAX_STEP_RATE_HZ + case STATUS_MAX_STEP_RATE_EXCEEDED: + printPgmString(PSTR("Step rate > 30kHz")); break; + #endif // Common g-code parser errors. case STATUS_GCODE_MODAL_GROUP_VIOLATION: printPgmString(PSTR("Modal group violation")); break; diff --git a/grbl/report.h b/grbl/report.h index cfd0d8b..e21df42 100644 --- a/grbl/report.h +++ b/grbl/report.h @@ -33,7 +33,7 @@ #define STATUS_ALARM_LOCK 9 #define STATUS_SOFT_LIMIT_ERROR 10 #define STATUS_OVERFLOW 11 -// #define STATUS_MAX_STEP_RATE_EXCEEDED 12 +#define STATUS_MAX_STEP_RATE_EXCEEDED 12 #define STATUS_GCODE_UNSUPPORTED_COMMAND 20 #define STATUS_GCODE_MODAL_GROUP_VIOLATION 21 @@ -54,12 +54,12 @@ #define STATUS_GCODE_UNUSED_WORDS 36 #define STATUS_GCODE_G43_DYNAMIC_AXIS_ERROR 37 -// Define Grbl alarm codes. Less than zero to distinguish alarm error from status error. -#define ALARM_HARD_LIMIT_ERROR -1 -#define ALARM_SOFT_LIMIT_ERROR -2 -#define ALARM_ABORT_CYCLE -3 -#define ALARM_PROBE_FAIL -4 -#define ALARM_HOMING_FAIL -5 +// Define Grbl alarm codes. +#define ALARM_HARD_LIMIT_ERROR 1 +#define ALARM_SOFT_LIMIT_ERROR 2 +#define ALARM_ABORT_CYCLE 3 +#define ALARM_PROBE_FAIL 4 +#define ALARM_HOMING_FAIL 5 // Define Grbl feedback message codes. #define MESSAGE_CRITICAL_EVENT 1 diff --git a/grbl/settings.c b/grbl/settings.c index 956cb02..87535d5 100644 --- a/grbl/settings.c +++ b/grbl/settings.c @@ -189,11 +189,15 @@ uint8_t settings_store_global_setting(uint8_t parameter, float value) { // Valid axis setting found. switch (set_idx) { case 0: - // if (value*settings.max_rate[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); } + #ifdef MAX_STEP_RATE_HZ + if (value*settings.max_rate[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); } + #endif settings.steps_per_mm[parameter] = value; break; case 1: - // if (value*settings.steps_per_mm[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); } + #ifdef MAX_STEP_RATE_HZ + if (value*settings.steps_per_mm[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); } + #endif settings.max_rate[parameter] = value; break; case 2: settings.acceleration[parameter] = value*60*60; break; // Convert to mm/min^2 for grbl internal use. From 76730176da0ddee2f31aea3e28e2df54342629c9 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Wed, 4 Mar 2015 06:50:26 -0700 Subject: [PATCH 37/40] Arduino IDE compatibility and minor homing fixes - Added an include in the right spot, if a user tries to compile and upload Grbl through the Arduino IDE with the old way. - Fixed a minor bug with homing max travel calculations. It was causing simultaneous axes homing to move slow than it did before. --- README.md | 2 +- grbl/config.h | 1 + grbl/grbl.h | 2 +- grbl/limits.c | 25 +++++++++++++++---------- grbl/protocol.c | 4 ++++ 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 962d932..afad1bb 100644 --- a/README.md +++ b/README.md @@ -82,5 +82,5 @@ List of Supported G-Codes in Grbl v0.9 ------------- Grbl is an open-source project and fueled by the free-time of our intrepid administrators and altruistic users. If you'd like to donate, all proceeds will be used to help fund supporting hardware and testing equipment. Thank you! -[![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=EBQWAWQAAT878) +[![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CUGXJHXA36BYW) diff --git a/grbl/config.h b/grbl/config.h index cde5065..2d6cb7c 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -27,6 +27,7 @@ #ifndef config_h #define config_h +#include "grbl.h" // For Arduino IDE compatibility. // Default settings. Used when resetting EEPROM. Change to desired name in defaults.h diff --git a/grbl/grbl.h b/grbl/grbl.h index ff92269..2122a50 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -23,7 +23,7 @@ // Grbl versioning system #define GRBL_VERSION "0.9i" -#define GRBL_VERSION_BUILD "20150223" +#define GRBL_VERSION_BUILD "20150302" // Define standard libraries used by Grbl. #include diff --git a/grbl/limits.c b/grbl/limits.c index 75b9f82..155aba5 100644 --- a/grbl/limits.c +++ b/grbl/limits.c @@ -134,7 +134,8 @@ void limits_go_home(uint8_t cycle_mask) float target[N_AXIS]; uint8_t limit_pin[N_AXIS], step_pin[N_AXIS]; - float max_travel; + + float max_travel = 0.0; for (idx=0; idx Date: Sat, 7 Mar 2015 13:32:59 -0700 Subject: [PATCH 38/40] Another homing cycle fix. - The homing cycle should be working again. Reverted it back to how it was about a month ago before I started to fiddle with it. Turns out that my past self knew what he was doing. --- grbl/grbl.h | 2 +- grbl/limits.c | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/grbl/grbl.h b/grbl/grbl.h index 2122a50..1ff036e 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -23,7 +23,7 @@ // Grbl versioning system #define GRBL_VERSION "0.9i" -#define GRBL_VERSION_BUILD "20150302" +#define GRBL_VERSION_BUILD "20150307" // Define standard libraries used by Grbl. #include diff --git a/grbl/limits.c b/grbl/limits.c index 155aba5..83d93d9 100644 --- a/grbl/limits.c +++ b/grbl/limits.c @@ -163,15 +163,19 @@ void limits_go_home(uint8_t cycle_mask) // Initialize and declare variables needed for homing routine. uint8_t axislock = 0; uint8_t n_active_axis = 0; - system_convert_array_steps_to_mpos(target,sys.position); + system_convert_array_steps_to_mpos(target,sys.position); for (idx=0; idx Date: Sat, 14 Mar 2015 09:27:48 -0600 Subject: [PATCH 39/40] Cleaned-up limit pin reporting and comments. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Cleaned up the limit pin state reporting option to display only the state per axis, rather than the whole port. It’s organized by an XYZ order, 0(low)-1(high), and generally looks like `Lim:001`. - Separated the control pin state reporting from limit state reporting as a new compile option. This stayed the same in terms of showing the entire port in binary, since it’s not anticipated that this will be used much, if at all. - Updated some of the gcode source comments regarding supported g-codes. --- grbl/config.h | 17 ++++++++++++----- grbl/gcode.c | 6 +++--- grbl/gcode.h | 9 +++++---- grbl/grbl.h | 2 +- grbl/report.c | 11 +++++++++-- 5 files changed, 30 insertions(+), 15 deletions(-) diff --git a/grbl/config.h b/grbl/config.h index 2d6cb7c..6efb761 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -156,11 +156,18 @@ // NOTE: Will eventually be added to Grbl settings in v1.0. // #define INVERT_CONTROL_PIN // Default disabled. Uncomment to enable. -// Enable input pin states feedback in status reports. The data is presented as a binary value with -// the bits in the appropriate input pin ports being 0(low) or 1(high). Useful for setting up a new -// CNC machine, but do not recommend keeping this option by default, as it will consume CPU resources -// with little to no benefit during normal operation. -// #define REPORT_INPUT_PIN_STATES // Default disabled. Uncomment to enable. +// Enable limit pin states feedback in status reports. The data is presented as 0 (low) or 1(high), +// where the order is XYZ. For example, if the Y- and Z-limit pins are active, Grbl will include the +// following string in the status report "Lim:011". This is generally useful for setting up a new +// CNC machine, but we do not recommend keeping this option enabled, as it will consume CPU resources +// with little to no benefit during normal operation and it may not be supported by most GUIs. +// #define REPORT_LIMIT_PIN_STATE // Default disabled. Uncomment to enable. + +// Enable control pin states feedback in status reports. The data is presented as simple binary of +// the control pin port (0 (low) or 1(high)), masked to show only the input pins. Non-control pins on the +// port will always show a 0 value. See cpu_map.h for the pin bitmap. As with the limit pin reporting, +// we do not recommend keeping this option enabled. Try to only use this for setting up a new CNC. +// #define REPORT_CONTROL_PIN_STATE // Default disabled. Uncomment to enable. // When Grbl powers-cycles or is hard reset with the Arduino reset button, Grbl boots up with no ALARM // by default. This is to make it as simple as possible for new users to start using Grbl. When homing diff --git a/grbl/gcode.c b/grbl/gcode.c index 37f9ff9..3893c61 100644 --- a/grbl/gcode.c +++ b/grbl/gcode.c @@ -1056,9 +1056,9 @@ uint8_t gc_execute_line(char *line) group 1 = {G81 - G89} (Motion modes: Canned cycles) group 4 = {M1} (Optional stop, ignored) group 6 = {M6} (Tool change) - group 7 = {G40, G41, G42} cutter radius compensation - group 8 = {G43} tool length offset (But G43.1/G94 IS SUPPORTED) - group 8 = {*M7} enable mist coolant + group 7 = {G41, G42} cutter radius compensation (G40 is supported) + group 8 = {G43} tool length offset (G43.1/G49 are supported) + group 8 = {*M7} enable mist coolant (* Compile-option) group 9 = {M48, M49} enable/disable feed and speed override switches group 10 = {G98, G99} return mode canned cycles group 13 = {G61, G61.1, G64} path control mode diff --git a/grbl/gcode.h b/grbl/gcode.h index 46df351..5331116 100644 --- a/grbl/gcode.h +++ b/grbl/gcode.h @@ -30,14 +30,14 @@ // and are similar/identical to other g-code interpreters by manufacturers (Haas,Fanuc,Mazak,etc). // NOTE: Modal group define values must be sequential and starting from zero. #define MODAL_GROUP_G0 0 // [G4,G10,G28,G28.1,G30,G30.1,G53,G92,G92.1] Non-modal -#define MODAL_GROUP_G1 1 // [G0,G1,G2,G3,G38.2,G80] Motion +#define MODAL_GROUP_G1 1 // [G0,G1,G2,G3,G38.2,G38.3,G38.4,G38.5,G80] Motion #define MODAL_GROUP_G2 2 // [G17,G18,G19] Plane selection #define MODAL_GROUP_G3 3 // [G90,G91] Distance mode -#define MODAL_GROUP_G4 4 // [G90.1,G91.1] Arc IJK distance mode +#define MODAL_GROUP_G4 4 // [G91.1] Arc IJK distance mode #define MODAL_GROUP_G5 5 // [G93,G94] Feed rate mode #define MODAL_GROUP_G6 6 // [G20,G21] Units #define MODAL_GROUP_G7 7 // [G40] Cutter radius compensation mode. G41/42 NOT SUPPORTED. -#define MODAL_GROUP_G8 8 // [G43,G43.1,G49] Tool length offset +#define MODAL_GROUP_G8 8 // [G43.1,G49] Tool length offset #define MODAL_GROUP_G12 9 // [G54,G55,G56,G57,G58,G59] Coordinate system selection #define MODAL_GROUP_M4 10 // [M0,M1,M2,M30] Stopping @@ -142,8 +142,9 @@ typedef struct { uint8_t feed_rate; // {G93,G94} uint8_t units; // {G20,G21} uint8_t distance; // {G90,G91} + // uint8_t distance_arc; // {G91.1} NOTE: Don't track. Only one supported. uint8_t plane_select; // {G17,G18,G19} - // uint8_t cutter_comp; // {G40} NOTE: Don't need to track since it's always disabled. + // uint8_t cutter_comp; // {G40} NOTE: Don't track. Only one supported. uint8_t tool_length; // {G43.1,G49} uint8_t coord_select; // {G54,G55,G56,G57,G58,G59} uint8_t program_flow; // {M0,M1,M2,M30} diff --git a/grbl/grbl.h b/grbl/grbl.h index 1ff036e..7b5bb1b 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -23,7 +23,7 @@ // Grbl versioning system #define GRBL_VERSION "0.9i" -#define GRBL_VERSION_BUILD "20150307" +#define GRBL_VERSION_BUILD "20150314" // Define standard libraries used by Grbl. #include diff --git a/grbl/report.c b/grbl/report.c index 9460f6a..e03bdde 100644 --- a/grbl/report.c +++ b/grbl/report.c @@ -484,9 +484,16 @@ void report_realtime_status() printFloat_RateValue(st_get_realtime_rate()); #endif - #ifdef REPORT_INPUT_PIN_STATES + #ifdef REPORT_LIMIT_PIN_STATE printPgmString(PSTR(",Lim:")); - print_uint8_base2(LIMIT_PIN & LIMIT_MASK); + uint8_t idx; + for (idx=0; idx Date: Sun, 15 Mar 2015 21:57:21 -0600 Subject: [PATCH 40/40] Updated README. - Also altered the G38.X reporting to save some bytes. --- README.md | 63 ++++++++++++++++++++++++++++++--------------------- grbl/gcode.h | 2 +- grbl/grbl.h | 2 +- grbl/report.c | 7 +++--- 4 files changed, 42 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index afad1bb..de9dfde 100644 --- a/README.md +++ b/README.md @@ -22,13 +22,15 @@ Grbl includes full acceleration management with look ahead. That means the contr *** _**Master Branch:**_ -* [Grbl v0.9g Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1m8E1Qa) _(2014-09-05)_ -* [Grbl v0.9g Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1kOAzig) _(2014-09-05)_ - - **IMPORTANT INFO WHEN UPGRADING TO GRBL v0.9g:** +* [Grbl v0.9i Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1EiviDk) _(2014-03-15)_ +* [Grbl v0.9i Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1NYIfKl) _(2015-03-15)_ + - **IMPORTANT INFO WHEN UPGRADING TO GRBL v0.9i:** - Baudrate is now **115200** (Up from 9600). - - Settings WILL be overwritten. Please make sure you have a backup. Also, settings have been renumbered and some have changed how they work. See our [Configuring v0.9 Wiki page](https://github.com/grbl/grbl/wiki/Configuring-Grbl-v0.9) for details. + - Variable spindle is now enabled by default. Z-limit(D12) and spindle enable(D11) have switched to access the hardware PWM on D11. Homing will not work if you do not re-wire your Z-limit switch to D12. _**Archives:**_ +* [Grbl v0.9g Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1m8E1Qa) +* [Grbl v0.9g Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1kOAzig) * [Grbl v0.8c Atmega328p 16mhz 9600baud](http://bit.ly/SSdCJE) * [Grbl v0.7d Atmega328p 16mhz 9600baud](http://bit.ly/ZhL15G) * [Grbl v0.6b Atmega328p 16mhz 9600baud](http://bit.ly/VD04A5) @@ -38,34 +40,43 @@ _**Archives:**_ *** -##Update Summary for v0.9 from v0.8 - - **IMPORTANT: Default serial baudrate is now 115200! (Up from 9600). And your settings will be over-written! Make sure to have a backup.** - - **_NEW_ Super Smooth Stepper Algorithm:** Complete overhaul of the handling of the stepper driver to simplify and reduce task time per ISR tick. Much smoother operation with the new Adaptive Multi-Axis Step Smoothing (AMASS) algorithm which does what its name implies (see stepper.c source for details). Users should immediately see significant improvements in how their machines move and overall performance! - - **Stability and Robustness Updates:** Grbl's overall stability has been focused on for this version. The planner and step-execution interface has been completely re-written for robustness and incorruptibility by the introduction of an intermediate step segment buffer that "checks-out" steps from the planner buffer in real-time. This means we can now fearlessly drive Grbl to it's highest limits. Combined with the new stepper algorithm and planner optimizations, this translated to **5x to 10x** overall performance increases in our testing! Also, stability and robustness tests have been reported to easily take 1.4 million (yes, **million**) line g-code programs like a champ! - - **(x4)+ Faster Planner:** Planning computations improved four-fold or more by optimizing end-to-end operations, which included streamlining the computations and introducing a planner pointer to locate un-improvable portions of the buffer and not waste cycles recomputing them. - - **Compile-able via Arduino IDE!:** Grbl's source code may be now download and altered, and then be compiled and flashed directly through the Arduino IDE, which should work on all platforms. See the Wiki for details on how to do it. - - **G-Code Parser Overhaul:** Completely re-written from the ground-up for 100%-compliance* to the g-code standard. (* Parts of the NIST standard are a bit out-dated and arbitrary, so we altered some minor things to make more sense. Differences are outlined in the source code.) We also took steps to allow us to break up the g-code parser into distinct separate tasks, which is key for some future development ideas and improvements. - - **Independent Acceleration and Velocity Settings:** Each axes may be defined with unique acceleration and velocity parameters and Grbl will automagically calculate the maximum acceleration and velocity through a path depending on the direction traveled. This is very useful for machines that have very different axes properties, like the ShapeOko's z-axis. - - **Soft Limits:** Checks if any motion command exceeds workspace limits before executing it, and alarms out, if detected. Another safety feature, but, unlike hard limits, position does not get lost, as it forces a feed hold before erroring out. NOTE: This still requires limit switches for homing so Grbl knows where the machine origin is, and the new max axis travel settings configured correctly for the machine. - - **Probing:** The G38.2 straight probe and G43.1/49 tool offset g-code commands are now supported. A simple probe switch must be connected to the Uno analog pin 5 (normally-open to ground). Grbl will report the probe position back to the user when the probing cycle detects a pin state change. - - **Tool Length Offsets:** Probing doesn't make sense without tool length offsets(TLO), so we added it! The G43.1 dynamic TLO (described by linuxcnc.org) and G49 TLO cancel commands are now supported. G43.1 dynamic TLO works like the normal G43 TLO(NOT SUPPORTED) but requires an additional axis word with the offset value attached. We did this so Grbl does not have to track and maintain a tool offset database in its memory. Perhaps in the future, we will support a tool database, but not for this version. - - **Improved Arc Performance:** The larger the arc radius, the faster Grbl will trace it! We are now defining arcs in terms of arc chordal tolerance, rather than a fixed segment length. This automatically scales the arc segment length such that maximum radial error of the segment from the true arc is never more than the chordal tolerance value of a super-accurate default of 0.002 mm. - - **CPU Pin Mapping:** In an effort for Grbl to be compatible with other AVR architectures, such as the 1280 or 2560, a new cpu_map.h pin configuration file has been created to allow Grbl to be compiled for them. This is currently user supported, so your mileage may vary. If you run across a bug, please let us know or better send us a fix! Thanks in advance! - - **New Grbl SIMULATOR! (by @jgeisler and @ashelly):** A completely independent wrapper of the Grbl main source code that may be compiled as an executable on a computer. No Arduino required. Simply simulates the responses of Grbl as if it was on an Arduino. May be used for many things: checking out how Grbl works, pre-process moves for GUI graphics, debugging of new features, etc. Much left to do, but potentially very powerful, as the dummy AVR variables can be written to output anything you need. - - **Configurable Real-time Status Reporting:** Users can now customize the type of real-time data Grbl reports back when they issue a '?' status report. This includes data such as: machine position, work position, planner buffer usage, serial RX buffer usage. - - **Updated Homing Routine:** Sets workspace volume in all negative space regardless of limit switch position. Common on pro CNCs. But, the behavior may be changed by a compile-time option though. Now tied directly into the main planner and stepper modules to reduce flash space and allow maximum speeds during seeking. +##Update Summary for v0.9i from v0.9h + - **IMPORTANT:** + - **Z-limit(D12) and spindle enable(D11) pins have switched to support variable spindle PWM!** + - **System tweaks: $14 cycle auto-start has been removed. No more QUEUE state.** + - **New G-Codes:** Additional probing cycle commands G38.3, G38.4, G38.5 now supported. G40 cutter radius compensation cancel. G91.1 arc IJK distance mode incremental. - **CoreXY Support:** Grbl now supports CoreXY kinematics on an introductory-level. Most functions have been verified to work, but there may be bugs here or there. Please report any problems you find! + - **Safety Door Support:** Safety door switches are now supported. Grbl will force a feed hold, shutdown the spindle and coolant, and wait until the door switch has closed and the user has issued a resume. Upon resuming, the spindle and coolant will re-energize after a configurable delay and continue. Useful for OEMs that require this feature. - **Full Limit and Control Pin Configurability:** Limits and control pins operation can now be interpreted by Grbl however you'd like, with the internal pull-up resistors enabled or disabled, or reading a high or low as a trigger. This should cover all wiring and NO or NC switch scenarios. - - **Optional Limit Pin Sharing:** Limit switches can be combined to share the same pins to free up precious I/O pins for other purposes. When combined, users must adjust the homing cycle mask in config.h to not home the axes on a shared pin at the same time. Don't worry; hard limits and the homing cycle still work just like they did before. - - **Optional Variable Spindle Speed Output:** Available only as a compile-time option through the config.h file. Enables PWM output for 'S' g-code commands. Enabling this feature will swap the Z-limit D11 pin and spindle enable D12 pin to access the hardware PWM on pin D12. The Z-limit pin, now on D12, should work just as it did before. - - **Additional Compile-Time Feature Options:** Line number tracking, real-time feed rate reporting. - - **SLATED FOR v1.0 DEVELOPMENT** Jogging controls and feedrate/spindle/coolant overrides. (In v0.9, the framework for feedrate overrides are in-place, only the minor details to complete it have yet to be installed.) + - **Additional Compile-Time Feature Options:** Limit/control pin state reporting, force power-up alarm state, GUI reporting mode, and more. + +##Update Summary for v0.9h from v0.8 + - **IMPORTANT: Default serial baudrate is now 115200! (Up from 9600)** + - **Super Smooth Stepper Algorithm** + - **Stability and Robustness Updates** + - **(x4)+ Faster Planner** + - **Compile-able via Arduino IDE!** + - **G-Code Parser Overhaul** + - **Independent Acceleration and Velocity Settings** + - **Soft Limits** + - **Probing** + - **Dynamic Tool Length Offsets** + - **Improved Arc Performance** + - **CPU Pin Mapping** + - **New Grbl SIMULATOR! (by @jgeisler and @ashelly)** + - **Configurable Real-time Status Reporting** + - **Updated Homing Routine** + - **CoreXY Support** + - **Full Limit and Control Pin Configurability** + - **Optional Limit Pin Sharing** + - **Optional Variable Spindle Speed Output** + - **Additional Compile-Time Feature Options** - ``` -List of Supported G-Codes in Grbl v0.9 +List of Supported G-Codes in Grbl v0.9i Master: - Non-Modal Commands: G4, G10 L2, G10 L20, G28, G30, G28.1, G30.1, G53, G92, G92.1 - - Motion Modes: G0, G1, G2, G3, G38.1, G80 + - Motion Modes: G0, G1, G2, G3, G38.1, G38.2, G38.3, G38.4, G80 - Feed Rate Modes: G93, G94 - Unit Modes: G20, G21 - Distance Modes: G90, G91 diff --git a/grbl/gcode.h b/grbl/gcode.h index 5331116..10d4792 100644 --- a/grbl/gcode.h +++ b/grbl/gcode.h @@ -68,7 +68,7 @@ #define MOTION_MODE_LINEAR 1 // G1 #define MOTION_MODE_CW_ARC 2 // G2 #define MOTION_MODE_CCW_ARC 3 // G3 -#define MOTION_MODE_PROBE_TOWARD 4 // G38.2 +#define MOTION_MODE_PROBE_TOWARD 4 // G38.2 NOTE: G38.2, G38.3, G38.4, G38.5 must be sequential. See report_gcode_modes(). #define MOTION_MODE_PROBE_TOWARD_NO_ERROR 5 // G38.3 #define MOTION_MODE_PROBE_AWAY 6 // G38.4 #define MOTION_MODE_PROBE_AWAY_NO_ERROR 7 // G38.5 diff --git a/grbl/grbl.h b/grbl/grbl.h index 7b5bb1b..17886ba 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -23,7 +23,7 @@ // Grbl versioning system #define GRBL_VERSION "0.9i" -#define GRBL_VERSION_BUILD "20150314" +#define GRBL_VERSION_BUILD "20150315" // Define standard libraries used by Grbl. #include diff --git a/grbl/report.c b/grbl/report.c index e03bdde..f573602 100644 --- a/grbl/report.c +++ b/grbl/report.c @@ -324,11 +324,10 @@ void report_gcode_modes() case MOTION_MODE_LINEAR : printPgmString(PSTR("G1")); break; case MOTION_MODE_CW_ARC : printPgmString(PSTR("G2")); break; case MOTION_MODE_CCW_ARC : printPgmString(PSTR("G3")); break; - case MOTION_MODE_PROBE_TOWARD : printPgmString(PSTR("G38.2")); break; - case MOTION_MODE_PROBE_TOWARD_NO_ERROR : printPgmString(PSTR("G38.3")); break; - case MOTION_MODE_PROBE_AWAY : printPgmString(PSTR("G38.4")); break; - case MOTION_MODE_PROBE_AWAY_NO_ERROR : printPgmString(PSTR("G38.5")); break; case MOTION_MODE_NONE : printPgmString(PSTR("G80")); break; + default: + printPgmString(PSTR("G38.")); + print_uint8_base10(gc_state.modal.motion - (MOTION_MODE_PROBE_TOWARD+2)); } printPgmString(PSTR(" G"));