Lot of refactoring for the future. CoreXY support.
- 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.
This commit is contained in:
parent
7e67395463
commit
9be7b3d930
27
config.h
27
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<<X_AXIS) and #define HOMING_CYCLE_1 (1<<Y_AXIS)
|
||||
// NOTE: This configuration option alters the motion of the X and Y axes to principle of operation
|
||||
// defined at (http://corexy.com/theory.html). Motors are assumed to positioned and wired exactly as
|
||||
// described, if not, motions may move in strange directions. Grbl assumes the CoreXY A and B motors
|
||||
// have the same steps per mm internally.
|
||||
// #define COREXY // Default disabled. Uncomment to enable.
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// ADVANCED CONFIGURATION OPTIONS:
|
||||
|
||||
@ -268,9 +285,7 @@
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// COMPILE-TIME ERROR CHECKING OF DEFINE VALUES:
|
||||
|
||||
// #if (ISR_TICKS_PER_ACCELERATION_TICK > 255)
|
||||
// #error Parameters ACCELERATION_TICKS / ISR_TICKS must be < 256 to prevent integer overflow.
|
||||
// #endif
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
150
cpu_map.h
150
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<<X_STEP_BIT)|(1<<Y_STEP_BIT)|(1<<Z_STEP_BIT)) // All step bits
|
||||
|
||||
// Define step direction output pins. NOTE: All direction pins must be on the same port.
|
||||
#define DIRECTION_DDR DDRD
|
||||
#define DIRECTION_PORT PORTD
|
||||
#define X_DIRECTION_BIT 5 // Uno Digital Pin 5
|
||||
#define Y_DIRECTION_BIT 6 // Uno Digital Pin 6
|
||||
#define Z_DIRECTION_BIT 7 // Uno Digital Pin 7
|
||||
#define DIRECTION_MASK ((1<<X_DIRECTION_BIT)|(1<<Y_DIRECTION_BIT)|(1<<Z_DIRECTION_BIT)) // All direction bits
|
||||
|
||||
// Define stepper driver enable/disable output pin.
|
||||
#define STEPPERS_DISABLE_DDR DDRB
|
||||
#define STEPPERS_DISABLE_PORT PORTB
|
||||
#define STEPPERS_DISABLE_BIT 0 // Uno Digital Pin 8
|
||||
#define STEPPERS_DISABLE_MASK (1<<STEPPERS_DISABLE_BIT)
|
||||
|
||||
// Define homing/hard limit switch input pins and limit interrupt vectors.
|
||||
// NOTE: All limit bit pins must be on the same port, but not on a port with other input pins (pinout).
|
||||
#define LIMIT_DDR DDRB
|
||||
#define LIMIT_PIN PINB
|
||||
#define LIMIT_PORT PORTB
|
||||
#define X_LIMIT_BIT 1 // Uno Digital Pin 9
|
||||
#define Y_LIMIT_BIT 2 // Uno Digital Pin 10
|
||||
#ifdef VARIABLE_SPINDLE // Z Limit pin and spindle enabled swapped to access hardware PWM on Pin 11.
|
||||
#define Z_LIMIT_BIT 4 // Uno Digital Pin 12
|
||||
#else
|
||||
#define Z_LIMIT_BIT 3 // Uno Digital Pin 11
|
||||
#endif
|
||||
#define LIMIT_MASK ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT)) // All limit bits
|
||||
#define LIMIT_INT PCIE0 // Pin change interrupt enable pin
|
||||
#define LIMIT_INT_vect PCINT0_vect
|
||||
#define LIMIT_PCMSK PCMSK0 // Pin change interrupt register
|
||||
|
||||
// Define spindle enable and spindle direction output pins.
|
||||
#define SPINDLE_ENABLE_DDR DDRB
|
||||
#define SPINDLE_ENABLE_PORT PORTB
|
||||
#ifdef VARIABLE_SPINDLE // Z Limit pin and spindle enabled swapped to access hardware PWM on Pin 11.
|
||||
#define SPINDLE_ENABLE_BIT 3 // Uno Digital Pin 11
|
||||
#else
|
||||
#define SPINDLE_ENABLE_BIT 4 // Uno Digital Pin 12
|
||||
#endif
|
||||
#define SPINDLE_DIRECTION_DDR DDRB
|
||||
#define SPINDLE_DIRECTION_PORT PORTB
|
||||
#define SPINDLE_DIRECTION_BIT 5 // Uno Digital Pin 13 (NOTE: D13 can't be pulled-high input due to LED.)
|
||||
|
||||
// Define flood and mist coolant enable output pins.
|
||||
// NOTE: Uno analog pins 4 and 5 are reserved for an i2c interface, and may be installed at
|
||||
// a later date if flash and memory space allows.
|
||||
#define COOLANT_FLOOD_DDR DDRC
|
||||
#define COOLANT_FLOOD_PORT PORTC
|
||||
#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 2 // Uno Analog Pin 2
|
||||
#endif
|
||||
|
||||
// Define user-control pinouts (cycle start, reset, feed hold) input pins.
|
||||
// NOTE: All pinouts pins must be on the same port and not on a port with other input pins (limits).
|
||||
#define PINOUT_DDR DDRC
|
||||
#define PINOUT_PIN PINC
|
||||
#define PINOUT_PORT PORTC
|
||||
#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
|
||||
#define PINOUT_MASK ((1<<PIN_RESET)|(1<<PIN_FEED_HOLD)|(1<<PIN_CYCLE_START))
|
||||
|
||||
// Define probe switch input pin.
|
||||
#define PROBE_DDR DDRC
|
||||
#define PROBE_PIN PINC
|
||||
#define PROBE_PORT PORTC
|
||||
#define PROBE_BIT 0 // Uno Analog Pin 0
|
||||
#define PROBE_MASK (1<<PROBE_BIT)
|
||||
|
||||
|
||||
#ifdef VARIABLE_SPINDLE
|
||||
// Advanced Configuration Below You should not need to touch these variables
|
||||
#define TCCRA_REGISTER TCCR2A
|
||||
#define TCCRB_REGISTER TCCR2B
|
||||
#define OCR_REGISTER OCR2A
|
||||
|
||||
#define COMB_BIT COM2A1
|
||||
#define WAVE0_REGISTER WGM20
|
||||
#define WAVE1_REGISTER WGM21
|
||||
#define WAVE2_REGISTER WGM22
|
||||
#define WAVE3_REGISTER WGM23
|
||||
|
||||
// NOTE: On the 328p, these must be the same as the SPINDLE_ENABLE settings.
|
||||
#define SPINDLE_PWM_DDR SPINDLE_ENABLE_DDR
|
||||
#define SPINDLE_PWM_PORT SPINDLE_ENABLE_PORT
|
||||
#define SPINDLE_PWM_BIT SPINDLE_ENABLE_BIT // Shared with SPINDLE_ENABLE.
|
||||
#endif // End of VARIABLE_SPINDLE
|
||||
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#ifdef CPU_MAP_ATMEGA2560 // (Arduino Mega 2560) Working @EliteEng
|
||||
@ -278,12 +167,12 @@
|
||||
#define STEP_MASK ((1<<X_STEP_BIT)|(1<<Y_STEP_BIT)|(1<<Z_STEP_BIT)) // All step bits
|
||||
|
||||
// Define step direction output pins. NOTE: All direction pins must be on the same port.
|
||||
#define DIRECTION_DDR DDRA
|
||||
#define DIRECTION_PORT PORTA
|
||||
#define DIRECTION_PIN PINA
|
||||
#define X_DIRECTION_BIT 5 // MEGA2560 Digital Pin 27
|
||||
#define Y_DIRECTION_BIT 6 // MEGA2560 Digital Pin 28
|
||||
#define Z_DIRECTION_BIT 7 // MEGA2560 Digital Pin 29
|
||||
#define DIRECTION_DDR DDRC
|
||||
#define DIRECTION_PORT PORTC
|
||||
#define DIRECTION_PIN PINC
|
||||
#define X_DIRECTION_BIT 7 // MEGA2560 Digital Pin 30
|
||||
#define Y_DIRECTION_BIT 6 // MEGA2560 Digital Pin 31
|
||||
#define Z_DIRECTION_BIT 5 // MEGA2560 Digital Pin 32
|
||||
#define DIRECTION_MASK ((1<<X_DIRECTION_BIT)|(1<<Y_DIRECTION_BIT)|(1<<Z_DIRECTION_BIT)) // All direction bits
|
||||
|
||||
// Define stepper driver enable/disable output pin.
|
||||
@ -347,20 +236,21 @@
|
||||
// Start of PWM & Stepper Enabled Spindle
|
||||
#ifdef VARIABLE_SPINDLE
|
||||
// Advanced Configuration Below You should not need to touch these variables
|
||||
// Set Timer up to use TIMER2B which is attached to Digital Pin 9
|
||||
#define TCCRA_REGISTER TCCR2A
|
||||
#define TCCRB_REGISTER TCCR2B
|
||||
#define OCR_REGISTER OCR2B
|
||||
// Set Timer up to use TIMER4B which is attached to Digital Pin 7
|
||||
#define PWM_MAX_VALUE 65535.0
|
||||
#define TCCRA_REGISTER TCCR4A
|
||||
#define TCCRB_REGISTER TCCR4B
|
||||
#define OCR_REGISTER OCR4B
|
||||
|
||||
#define COMB_BIT COM2B1
|
||||
#define WAVE0_REGISTER WGM20
|
||||
#define WAVE1_REGISTER WGM21
|
||||
#define WAVE2_REGISTER WGM22
|
||||
#define WAVE3_REGISTER WGM23
|
||||
#define COMB_BIT COM4B1
|
||||
#define WAVE0_REGISTER WGM40
|
||||
#define WAVE1_REGISTER WGM41
|
||||
#define WAVE2_REGISTER WGM42
|
||||
#define WAVE3_REGISTER WGM43
|
||||
|
||||
#define SPINDLE_PWM_DDR DDRH
|
||||
#define SPINDLE_PWM_PORT PORTH
|
||||
#define SPINDLE_PWM_BIT 6 // MEGA2560 Digital Pin 9
|
||||
#define SPINDLE_PWM_BIT 4 // MEGA2560 Digital Pin 97
|
||||
#endif // End of VARIABLE_SPINDLE
|
||||
|
||||
#endif
|
||||
|
@ -2,7 +2,7 @@
|
||||
defaults.h - defaults settings 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
|
||||
|
32
gcode.c
32
gcode.c
@ -2,7 +2,7 @@
|
||||
gcode.c - rs274/ngc parser.
|
||||
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
|
||||
@ -66,10 +66,7 @@ void gc_init()
|
||||
// limit pull-off routines.
|
||||
void gc_sync_position()
|
||||
{
|
||||
uint8_t i;
|
||||
for (i=0; i<N_AXIS; i++) {
|
||||
gc_state.position[i] = sys.position[i]/settings.steps_per_mm[i];
|
||||
}
|
||||
system_convert_array_steps_to_mpos(gc_state.position,sys.position);
|
||||
}
|
||||
|
||||
|
||||
@ -243,6 +240,12 @@ uint8_t gc_execute_line(char *line)
|
||||
if (int_value == 20) { gc_block.modal.units = UNITS_MODE_INCHES; } // G20
|
||||
else { gc_block.modal.units = UNITS_MODE_MM; } // G21
|
||||
break;
|
||||
case 40:
|
||||
word_bit = MODAL_GROUP_G7;
|
||||
// NOTE: Not required since cutter radius compensation is always disabled. Only here
|
||||
// to support G40 commands that often appear in g-code program headers to setup defaults.
|
||||
// gc_block.modal.cutter_comp = CUTTER_COMP_DISABLE; // G40
|
||||
break;
|
||||
case 43: case 49:
|
||||
word_bit = MODAL_GROUP_G8;
|
||||
// NOTE: The NIST g-code standard vaguely states that when a tool length offset is changed,
|
||||
@ -488,7 +491,10 @@ uint8_t gc_execute_line(char *line)
|
||||
}
|
||||
}
|
||||
|
||||
// [13. Cutter radius compensation ]: NOT SUPPORTED. Error, if G53 is active.
|
||||
// [13. Cutter radius compensation ]: G41/42 NOT SUPPORTED. Error, if enabled while G53 is active.
|
||||
// [G40 Errors]: G2/3 arc is programmed after a G40. The linear move after disabling is less than tool diameter.
|
||||
// NOTE: Since cutter radius compensation is never enabled, these G40 errors don't apply. Grbl supports G40
|
||||
// only for the purpose to not error when G40 is sent with a g-code program header to setup the default modes.
|
||||
|
||||
// [14. Cutter length compensation ]: G43 NOT SUPPORTED, but G43.1 and G49 are.
|
||||
// [G43.1 Errors]: Motion command in same line.
|
||||
@ -839,10 +845,9 @@ uint8_t gc_execute_line(char *line)
|
||||
|
||||
// [4. Set spindle speed ]:
|
||||
if (gc_state.spindle_speed != gc_block.values.s) {
|
||||
gc_state.spindle_speed = gc_block.values.s;
|
||||
|
||||
// Update running spindle only if not in check mode and not already enabled.
|
||||
if (gc_state.modal.spindle != SPINDLE_DISABLE) { spindle_run(gc_state.modal.spindle, gc_state.spindle_speed); }
|
||||
if (gc_state.modal.spindle != SPINDLE_DISABLE) { spindle_run(gc_state.modal.spindle, gc_block.values.s); }
|
||||
gc_state.spindle_speed = gc_block.values.s;
|
||||
}
|
||||
|
||||
// [5. Select tool ]: NOT SUPPORTED. Only tracks tool value.
|
||||
@ -852,15 +857,15 @@ uint8_t gc_execute_line(char *line)
|
||||
|
||||
// [7. Spindle control ]:
|
||||
if (gc_state.modal.spindle != gc_block.modal.spindle) {
|
||||
gc_state.modal.spindle = gc_block.modal.spindle;
|
||||
// Update spindle control and apply spindle speed when enabling it in this block.
|
||||
spindle_run(gc_state.modal.spindle, gc_state.spindle_speed);
|
||||
spindle_run(gc_block.modal.spindle, gc_state.spindle_speed);
|
||||
gc_state.modal.spindle = gc_block.modal.spindle;
|
||||
}
|
||||
|
||||
// [8. Coolant control ]:
|
||||
if (gc_state.modal.coolant != gc_block.modal.coolant) {
|
||||
coolant_run(gc_block.modal.coolant);
|
||||
gc_state.modal.coolant = gc_block.modal.coolant;
|
||||
coolant_run(gc_state.modal.coolant);
|
||||
}
|
||||
|
||||
// [9. Enable/disable feed rate or spindle overrides ]: NOT SUPPORTED
|
||||
@ -874,7 +879,8 @@ uint8_t gc_execute_line(char *line)
|
||||
// [12. Set length units ]:
|
||||
gc_state.modal.units = gc_block.modal.units;
|
||||
|
||||
// [13. Cutter radius compensation ]: NOT SUPPORTED
|
||||
// [13. Cutter radius compensation ]: G41/42 NOT SUPPORTED
|
||||
// gc_state.modal.cutter_comp = gc_block.modal.cutter_comp; // NOTE: Not needed since always disabled.
|
||||
|
||||
// [14. Cutter length compensation ]: G43.1 and G49 supported. G43 NOT SUPPORTED.
|
||||
// NOTE: If G43 were supported, its operation wouldn't be any different from G43.1 in terms
|
||||
|
23
gcode.h
23
gcode.h
@ -2,7 +2,7 @@
|
||||
gcode.h - rs274/ngc parser.
|
||||
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
|
||||
@ -40,16 +40,17 @@
|
||||
#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_G8 6 // [G43,G43.1,G49] Tool length offset
|
||||
#define MODAL_GROUP_G12 7 // [G54,G55,G56,G57,G58,G59] Coordinate system selection
|
||||
#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_M4 8 // [M0,M1,M2,M30] Stopping
|
||||
#define MODAL_GROUP_M7 9 // [M3,M4,M5] Spindle turning
|
||||
#define MODAL_GROUP_M8 10 // [M7,M8,M9] Coolant control
|
||||
#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 OTHER_INPUT_F 11
|
||||
#define OTHER_INPUT_S 12
|
||||
#define OTHER_INPUT_T 13
|
||||
#define OTHER_INPUT_F 12
|
||||
#define OTHER_INPUT_S 13
|
||||
#define OTHER_INPUT_T 14
|
||||
|
||||
// Define command actions for within execution-type modal groups (motion, stopping, non-modal). Used
|
||||
// internally by the parser to know which command to execute.
|
||||
@ -99,6 +100,9 @@
|
||||
#define UNITS_MODE_MM 0 // G21 (Default: Must be zero)
|
||||
#define UNITS_MODE_INCHES 1 // G20
|
||||
|
||||
// Modal Group G7: Cutter radius compensation mode
|
||||
#define CUTTER_COMP_DISABLE 0 // G40 (Default: Must be zero)
|
||||
|
||||
// Modal Group M7: Spindle control
|
||||
#define SPINDLE_DISABLE 0 // M5 (Default: Must be zero)
|
||||
#define SPINDLE_ENABLE_CW 1 // M3
|
||||
@ -140,6 +144,7 @@ typedef struct {
|
||||
uint8_t units; // {G20,G21}
|
||||
uint8_t distance; // {G90,G91}
|
||||
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 tool_length; // {G43.1,G49}
|
||||
uint8_t coord_select; // {G54,G55,G56,G57,G58,G59}
|
||||
uint8_t program_flow; // {M0,M1,M2,M30}
|
||||
|
49
grbl.h
Normal file
49
grbl.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
grbl.h - include file
|
||||
Part of Grbl v0.9
|
||||
|
||||
Copyright (c) 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
|
||||
(at your option) any later version.
|
||||
|
||||
Grbl is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// 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
|
101
limits.c
101
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<<WDIE); // Disable watchdog timer.
|
||||
if (sys.state != STATE_ALARM) { // Ignore if already in alarm state.
|
||||
if (bit_isfalse(sys.execute,EXEC_ALARM)) {
|
||||
if (!(sys.rt_exec_alarm)) {
|
||||
uint8_t bits = LIMIT_PIN;
|
||||
// Check limit pin state.
|
||||
if (bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { bits ^= LIMIT_MASK; }
|
||||
if (bits & LIMIT_MASK) {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -121,7 +121,7 @@ void limits_disable()
|
||||
// the trigger point of the limit switches. The rapid stops are handled by a system level axis lock
|
||||
// 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.
|
||||
// NOTE: Only the abort realtime 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)
|
||||
{
|
||||
@ -140,6 +140,9 @@ void limits_go_home(uint8_t cycle_mask)
|
||||
// Initialize limit and step pin masks
|
||||
limit_pin[idx] = get_limit_pin_mask(idx);
|
||||
step_pin[idx] = get_step_pin_mask(idx);
|
||||
#ifdef COREXY
|
||||
if ((idx==A_MOTOR)||(idx==B_MOTOR)) { step_pin[idx] = (get_step_pin_mask(X_AXIS)|get_step_pin_mask(Y_AXIS)); }
|
||||
#endif
|
||||
|
||||
// Determine travel distance to the furthest homing switch based on user max travel settings.
|
||||
// NOTE: settings.max_travel[] is stored as a negative value.
|
||||
@ -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.
|
||||
@ -158,18 +162,21 @@ void limits_go_home(uint8_t cycle_mask)
|
||||
uint8_t n_active_axis = 0;
|
||||
uint8_t axislock = 0;
|
||||
|
||||
system_convert_array_steps_to_mpos(target,sys.position);
|
||||
for (idx=0; idx<N_AXIS; idx++) {
|
||||
// Set target location for active axes and setup computation for homing rate.
|
||||
if (bit_istrue(cycle_mask,bit(idx))) {
|
||||
n_active_axis++;
|
||||
if (!approach) { target[idx] = -max_travel; }
|
||||
else { target[idx] = max_travel; }
|
||||
} else {
|
||||
target[idx] = 0.0;
|
||||
}
|
||||
|
||||
if (!approach) {
|
||||
// Set target direction based on cycle mask
|
||||
if (bit_istrue(settings.homing_dir_mask,bit(idx))) { target[idx] = -target[idx]; }
|
||||
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; }
|
||||
}
|
||||
}
|
||||
|
||||
// Apply axislock to the step port pins active in this cycle.
|
||||
if (bit_istrue(cycle_mask,bit(idx))) { axislock |= step_pin[idx]; }
|
||||
@ -199,12 +206,14 @@ void limits_go_home(uint8_t cycle_mask)
|
||||
}
|
||||
sys.homing_axis_lock = axislock;
|
||||
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_runtime() in this loop.
|
||||
if (sys.execute & EXEC_RESET) { protocol_execute_runtime(); return; }
|
||||
// Check only for user reset. No time to run protocol_execute_realtime() in this loop.
|
||||
|
||||
if (sys.rt_exec_state & EXEC_RESET) { protocol_execute_realtime(); return; }
|
||||
} while (STEP_MASK & axislock);
|
||||
|
||||
st_reset(); // Immediately force kill steppers and reset step segment buffer.
|
||||
plan_reset(); // Reset planner buffer. Zero planner positions. Ensure homing motion is cleared.
|
||||
plan_sync_position(); // Sync planner position to current machine position
|
||||
|
||||
delay_ms(settings.homing_debounce_delay); // Delay to allow transient dynamics to dissipate.
|
||||
|
||||
@ -220,33 +229,60 @@ void limits_go_home(uint8_t cycle_mask)
|
||||
// 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
|
||||
// triggering when hard limits are enabled or when more than one axes shares a limit pin.
|
||||
#ifdef COREXY
|
||||
int32_t off_axis_position = 0;
|
||||
#endif
|
||||
int32_t set_axis_position;
|
||||
// Set machine positions for homed limit switches. Don't update non-homed axes.
|
||||
for (idx=0; idx<N_AXIS; idx++) {
|
||||
// Set up pull off targets and machine positions for limit switches homed in the negative
|
||||
// direction, rather than the traditional positive. Leave non-homed positions as zero and
|
||||
// do not move them.
|
||||
// NOTE: settings.max_travel[] is stored as a negative value.
|
||||
if (cycle_mask & bit(idx)) {
|
||||
set_axis_position = 0;
|
||||
#ifndef HOMING_FORCE_SET_ORIGIN
|
||||
if ( bit_istrue(settings.homing_dir_mask,bit(idx)) ) {
|
||||
set_axis_position = lround(settings.max_travel[idx]*settings.steps_per_mm[idx]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef COREXY
|
||||
if (idx==X_AXIS) {
|
||||
off_axis_position = (sys.position[B_MOTOR] - sys.position[A_MOTOR])/2;
|
||||
sys.position[A_MOTOR] = set_axis_position - off_axis_position;
|
||||
sys.position[B_MOTOR] = set_axis_position + off_axis_position;
|
||||
} else if (idx==Y_AXIS) {
|
||||
off_axis_position = (sys.position[A_MOTOR] + sys.position[B_MOTOR])/2;
|
||||
sys.position[A_MOTOR] = off_axis_position - set_axis_position;
|
||||
sys.position[B_MOTOR] = off_axis_position + set_axis_position;
|
||||
} else {
|
||||
sys.position[idx] = set_axis_position;
|
||||
}
|
||||
#else
|
||||
sys.position[idx] = set_axis_position;
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
plan_sync_position(); // Sync planner position to homed machine position.
|
||||
|
||||
// Set pull-off motion target. Seperated from above loop if target is dependent on sys.position.
|
||||
if (settings.homing_pulloff > 0.0) {
|
||||
for (idx=0; idx<N_AXIS; idx++) {
|
||||
if (cycle_mask & bit(idx)) {
|
||||
#ifdef HOMING_FORCE_SET_ORIGIN
|
||||
sys.position[idx] = 0; // Set axis homed location as axis origin
|
||||
target[idx] = settings.homing_pulloff;
|
||||
if ( bit_isfalse(settings.homing_dir_mask,bit(idx)) ) { target[idx] = -target[idx]; }
|
||||
#else
|
||||
if ( bit_istrue(settings.homing_dir_mask,bit(idx)) ) {
|
||||
target[idx] = settings.homing_pulloff+settings.max_travel[idx];
|
||||
sys.position[idx] = lround(settings.max_travel[idx]*settings.steps_per_mm[idx]);
|
||||
} else {
|
||||
target[idx] = -settings.homing_pulloff;
|
||||
sys.position[idx] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
} else { // Non-active cycle axis. Set target to not move during pull-off.
|
||||
target[idx] = (float)sys.position[idx]/settings.steps_per_mm[idx];
|
||||
} else {
|
||||
// Non-active cycle axis. Set target to not move during pull-off.
|
||||
target[idx] = system_convert_axis_steps_to_mpos(sys.position, idx);
|
||||
}
|
||||
}
|
||||
plan_sync_position(); // Sync planner position to current machine position for pull-off move.
|
||||
|
||||
#ifdef USE_LINE_NUMBERS
|
||||
plan_buffer_line(target, settings.homing_seek_rate, false, HOMING_CYCLE_LINE_NUMBER); // Bypass mc_line(). Directly plan motion.
|
||||
#else
|
||||
@ -256,9 +292,10 @@ void limits_go_home(uint8_t cycle_mask)
|
||||
// Initiate pull-off using main motion control routines.
|
||||
// TODO : Clean up state routines so that this motion still shows homing state.
|
||||
sys.state = STATE_QUEUED;
|
||||
bit_true_atomic(sys.execute, EXEC_CYCLE_START);
|
||||
protocol_execute_runtime();
|
||||
bit_true_atomic(sys.rt_exec_state, EXEC_CYCLE_START);
|
||||
protocol_execute_realtime();
|
||||
protocol_buffer_synchronize(); // Complete pull-off motion.
|
||||
}
|
||||
|
||||
// Set system state to homing before returning.
|
||||
sys.state = STATE_HOMING;
|
||||
@ -291,16 +328,16 @@ void limits_soft_check(float *target)
|
||||
// workspace volume so just come to a controlled stop so position is not lost. When complete
|
||||
// enter alarm mode.
|
||||
if (sys.state == STATE_CYCLE) {
|
||||
bit_true_atomic(sys.execute, EXEC_FEED_HOLD);
|
||||
bit_true_atomic(sys.rt_exec_state, EXEC_FEED_HOLD);
|
||||
do {
|
||||
protocol_execute_runtime();
|
||||
protocol_execute_realtime();
|
||||
if (sys.abort) { return; }
|
||||
} while ( sys.state != STATE_IDLE || sys.state != STATE_QUEUED);
|
||||
}
|
||||
|
||||
mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown.
|
||||
bit_true_atomic(sys.execute, (EXEC_ALARM | EXEC_CRIT_EVENT)); // Indicate soft limit critical event
|
||||
protocol_execute_runtime(); // Execute to enter critical event loop and system abort
|
||||
bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_SOFT_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate soft limit critical event
|
||||
protocol_execute_realtime(); // Execute to enter critical event loop and system abort
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
2
limits.h
2
limits.h
@ -2,7 +2,7 @@
|
||||
limits.h - 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
|
||||
|
5
main.c
5
main.c
@ -2,7 +2,7 @@
|
||||
main.c - An embedded CNC Controller with rs274/ngc (g-code) support
|
||||
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,7 +89,8 @@ int main(void)
|
||||
|
||||
// Reset system variables.
|
||||
sys.abort = false;
|
||||
sys.execute = 0;
|
||||
sys.rt_exec_state = 0;
|
||||
sys.rt_exec_alarm = 0;
|
||||
if (bit_istrue(settings.flags,BITFLAG_AUTO_START)) { sys.auto_start = true; }
|
||||
else { sys.auto_start = false; }
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
motion_control.c - high level interface for issuing motion commands
|
||||
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
|
||||
@ -76,12 +76,13 @@
|
||||
// If the buffer is full: good! That means we are well ahead of the robot.
|
||||
// Remain in this loop until there is room in the buffer.
|
||||
do {
|
||||
protocol_execute_runtime(); // Check for any run-time commands
|
||||
protocol_execute_realtime(); // Check for any run-time commands
|
||||
if (sys.abort) { return; } // Bail, if system abort.
|
||||
if ( plan_check_full_buffer() ) { protocol_auto_cycle_start(); } // Auto-cycle start when buffer is full.
|
||||
else { break; }
|
||||
} while (1);
|
||||
|
||||
// Plan and queue motion into planner buffer
|
||||
#ifdef USE_LINE_NUMBERS
|
||||
plan_buffer_line(target, feed_rate, invert_feed_rate, line_number);
|
||||
#else
|
||||
@ -227,8 +228,8 @@ void mc_dwell(float seconds)
|
||||
protocol_buffer_synchronize();
|
||||
delay_ms(floor(1000*seconds-i*DWELL_TIME_STEP)); // Delay millisecond remainder.
|
||||
while (i-- > 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.
|
||||
#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.execute, (EXEC_ALARM | EXEC_CRIT_EVENT)); // Indicate homing limit critical event
|
||||
bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
sys.state = STATE_HOMING; // Set system state variable
|
||||
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; idx<N_AXIS; idx++){
|
||||
// NOTE: The target[] variable updated here will be sent back and synced with the g-code parser.
|
||||
target[idx] = (float)sys.position[idx]/settings.steps_per_mm[idx];
|
||||
}
|
||||
system_convert_array_steps_to_mpos(target, sys.position);
|
||||
|
||||
sys.auto_start = auto_start_state; // Restore run state before returning
|
||||
// Restore run state before returning
|
||||
sys.auto_start = auto_start_state;
|
||||
|
||||
#ifdef MESSAGE_PROBE_COORDINATES
|
||||
// All done! Output the probe position as message.
|
||||
@ -364,16 +360,16 @@ void mc_homing_cycle()
|
||||
}
|
||||
|
||||
|
||||
// Method to ready the system to reset by setting the runtime reset command and killing any
|
||||
// Method to ready the system to reset by setting the realtime reset command and killing any
|
||||
// active processes in the system. This also checks if a system reset is issued while Grbl
|
||||
// is in a motion state. If so, kills the steppers and sets the system alarm to flag position
|
||||
// lost, since there was an abrupt uncontrolled deceleration. Called at an interrupt level by
|
||||
// runtime abort command and hard limits. So, keep to a minimum.
|
||||
// realtime abort command and hard limits. So, keep to a minimum.
|
||||
void mc_reset()
|
||||
{
|
||||
// Only this function can set the system reset. Helps prevent multiple kill calls.
|
||||
if (bit_isfalse(sys.execute, EXEC_RESET)) {
|
||||
bit_true_atomic(sys.execute, EXEC_RESET);
|
||||
if (bit_isfalse(sys.rt_exec_state, EXEC_RESET)) {
|
||||
bit_true_atomic(sys.rt_exec_state, EXEC_RESET);
|
||||
|
||||
// Kill spindle and coolant.
|
||||
spindle_stop();
|
||||
@ -384,7 +380,7 @@ 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_HOLD | STATE_HOMING)) {
|
||||
bit_true_atomic(sys.execute, EXEC_ALARM); // Flag main program to execute alarm state.
|
||||
bit_true_atomic(sys.rt_exec_alarm, EXEC_ALARM_ABORT_CYCLE);
|
||||
st_go_idle(); // Force kill steppers. Position has likely been lost.
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
motion_control.h - high level interface for issuing motion commands
|
||||
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
|
||||
|
@ -2,7 +2,7 @@
|
||||
nuts_bolts.c - Shared functions
|
||||
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
|
||||
|
14
nuts_bolts.h
14
nuts_bolts.h
@ -2,7 +2,7 @@
|
||||
nuts_bolts.h - Header file for shared definitions, variables, and functions
|
||||
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
|
||||
@ -30,15 +30,23 @@
|
||||
#define false 0
|
||||
#define true 1
|
||||
|
||||
// Axis array index values. Must start with 0 and be continuous.
|
||||
#define N_AXIS 3 // Number of axes
|
||||
#define X_AXIS 0 // Axis indexing value. Must start with 0 and be continuous.
|
||||
#define X_AXIS 0 // Axis indexing value.
|
||||
#define Y_AXIS 1
|
||||
#define Z_AXIS 2
|
||||
// #define A_AXIS 3
|
||||
|
||||
// CoreXY motor assignments. DO NOT ALTER.
|
||||
// NOTE: If the A and B motor axis bindings are changed, this effects the CoreXY equations.
|
||||
#ifdef COREXY
|
||||
#define A_MOTOR X_AXIS // Must be X_AXIS
|
||||
#define B_MOTOR Y_AXIS // Must be Y_AXIS
|
||||
#endif
|
||||
|
||||
// Conversions
|
||||
#define MM_PER_INCH (25.40)
|
||||
#define INCH_PER_MM (0.0393701)
|
||||
|
||||
#define TICKS_PER_MICROSECOND (F_CPU/1000000)
|
||||
|
||||
// Useful macros
|
||||
|
47
planner.c
47
planner.c
@ -2,7 +2,7 @@
|
||||
planner.c - buffers movement commands and manages the acceleration profile plan
|
||||
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
|
||||
@ -284,17 +284,36 @@ uint8_t plan_check_full_buffer()
|
||||
int32_t target_steps[N_AXIS];
|
||||
float unit_vec[N_AXIS], delta_mm;
|
||||
uint8_t idx;
|
||||
for (idx=0; idx<N_AXIS; idx++) {
|
||||
// Calculate target position in absolute steps. This conversion should be consistent throughout.
|
||||
target_steps[idx] = lround(target[idx]*settings.steps_per_mm[idx]);
|
||||
#ifdef COREXY
|
||||
target_steps[A_MOTOR] = lround(target[A_MOTOR]*settings.steps_per_mm[A_MOTOR]);
|
||||
target_steps[B_MOTOR] = lround(target[B_MOTOR]*settings.steps_per_mm[B_MOTOR]);
|
||||
block->steps[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
|
||||
|
||||
// Number of steps for each axis and determine max step events
|
||||
for (idx=0; idx<N_AXIS; idx++) {
|
||||
// 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.
|
||||
#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]);
|
||||
|
||||
// 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];
|
||||
#endif
|
||||
unit_vec[idx] = delta_mm; // Store unit vector numerator. Denominator computed later.
|
||||
|
||||
// Set direction bits. Bit enabled always means direction is negative.
|
||||
@ -403,10 +422,22 @@ 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<N_AXIS; idx++) {
|
||||
#ifdef COREXY
|
||||
if (idx==A_MOTOR) {
|
||||
pl.position[idx] = (sys.position[A_MOTOR] + sys.position[B_MOTOR])/2;
|
||||
} else if (idx==B_MOTOR) {
|
||||
pl.position[idx] = (sys.position[A_MOTOR] - sys.position[B_MOTOR])/2;
|
||||
} else {
|
||||
pl.position[idx] = sys.position[idx];
|
||||
}
|
||||
#else
|
||||
pl.position[idx] = sys.position[idx];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
planner.h - buffers movement commands and manages the acceleration profile plan
|
||||
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
|
||||
|
2
print.c
2
print.c
@ -2,7 +2,7 @@
|
||||
print.c - Functions for formatting output strings
|
||||
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
|
||||
|
2
print.h
2
print.h
@ -2,7 +2,7 @@
|
||||
print.h - Functions for formatting output strings
|
||||
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
|
||||
|
4
probe.c
4
probe.c
@ -2,7 +2,7 @@
|
||||
probe.c - code pertaining to probing methods
|
||||
Part of Grbl v0.9
|
||||
|
||||
Copyright (c) 2014 Sungeun K. Jeon
|
||||
Copyright (c) 2014-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
|
||||
@ -63,7 +63,7 @@ void probe_state_monitor()
|
||||
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);
|
||||
bit_true(sys.rt_exec_state, EXEC_FEED_HOLD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
2
probe.h
2
probe.h
@ -2,7 +2,7 @@
|
||||
probe.h - code pertaining to probing methods
|
||||
Part of Grbl v0.9
|
||||
|
||||
Copyright (c) 2014 Sungeun K. Jeon
|
||||
Copyright (c) 2014-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
|
||||
|
71
protocol.c
71
protocol.c
@ -2,7 +2,7 @@
|
||||
protocol.c - controls Grbl execution protocol and procedures
|
||||
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,7 +43,7 @@ static char line[LINE_BUFFER_SIZE]; // Line to be executed. Zero-terminated.
|
||||
// such as settings, initiating the homing cycle, and toggling switch states.
|
||||
static void protocol_execute_line(char *line)
|
||||
{
|
||||
protocol_execute_runtime(); // Runtime command check point.
|
||||
protocol_execute_realtime(); // Runtime command check point.
|
||||
if (sys.abort) { return; } // Bail to calling function upon system abort
|
||||
|
||||
if (line[0] == 0) {
|
||||
@ -160,7 +160,7 @@ void protocol_main_loop()
|
||||
// completed. In either case, auto-cycle start, if enabled, any queued moves.
|
||||
protocol_auto_cycle_start();
|
||||
|
||||
protocol_execute_runtime(); // Runtime command check point.
|
||||
protocol_execute_realtime(); // Runtime command check point.
|
||||
if (sys.abort) { return; } // Bail to main() program loop to reset system.
|
||||
|
||||
}
|
||||
@ -172,50 +172,52 @@ void protocol_main_loop()
|
||||
// Executes run-time commands, when required. This is called from various check points in the main
|
||||
// program, primarily where there may be a while loop waiting for a buffer to clear space or any
|
||||
// point where the execution time from the last check point may be more than a fraction of a second.
|
||||
// This is a way to execute runtime commands asynchronously (aka multitasking) with grbl's g-code
|
||||
// This is a way to execute realtime commands asynchronously (aka multitasking) with grbl's g-code
|
||||
// parsing and planning functions. This function also serves as an interface for the interrupts to
|
||||
// set the system runtime flags, where only the main program handles them, removing the need to
|
||||
// set the system realtime flags, where only the main program handles them, removing the need to
|
||||
// define more computationally-expensive volatile variables. This also provides a controlled way to
|
||||
// execute certain tasks without having two or more instances of the same task, such as the planner
|
||||
// recalculating the buffer upon a feedhold or override.
|
||||
// NOTE: The sys.execute variable flags are set by any process, step or serial interrupts, pinouts,
|
||||
// NOTE: The sys.rt_exec_state variable flags are set by any process, step or serial interrupts, pinouts,
|
||||
// limit switches, or the main program.
|
||||
void protocol_execute_runtime()
|
||||
void protocol_execute_realtime()
|
||||
{
|
||||
uint8_t rt_exec = sys.execute; // Copy to avoid calling volatile multiple times
|
||||
if (rt_exec) { // Enter only if any bit flag is true
|
||||
uint8_t rt_exec; // Temp variable to avoid calling volatile multiple times.
|
||||
|
||||
// Check and execute alarms.
|
||||
rt_exec = sys.rt_exec_alarm; // Copy volatile sys.rt_exec_alarm.
|
||||
if (rt_exec) { // Enter only if any bit flag is true
|
||||
// System alarm. Everything has shutdown by something that has gone severely wrong. Report
|
||||
// the source of the error to the user. If critical, Grbl disables by entering an infinite
|
||||
// loop until system reset/abort.
|
||||
if (rt_exec & (EXEC_ALARM | EXEC_CRIT_EVENT)) {
|
||||
sys.state = STATE_ALARM; // Set system alarm state
|
||||
|
||||
// Critical events. Hard/soft limit events identified by both critical event and alarm exec
|
||||
// flags. Probe fail is identified by the critical event exec flag only.
|
||||
if (rt_exec & EXEC_CRIT_EVENT) {
|
||||
if (rt_exec & EXEC_ALARM) { report_alarm_message(ALARM_LIMIT_ERROR); }
|
||||
else { report_alarm_message(ALARM_PROBE_FAIL); }
|
||||
if (rt_exec & EXEC_ALARM_HARD_LIMIT) {
|
||||
report_alarm_message(ALARM_HARD_LIMIT_ERROR);
|
||||
} else if (rt_exec & EXEC_ALARM_SOFT_LIMIT) {
|
||||
report_alarm_message(ALARM_SOFT_LIMIT_ERROR);
|
||||
} else if (rt_exec & EXEC_ALARM_ABORT_CYCLE) {
|
||||
report_alarm_message(ALARM_ABORT_CYCLE);
|
||||
} else if (rt_exec & EXEC_ALARM_PROBE_FAIL) {
|
||||
report_alarm_message(ALARM_PROBE_FAIL);
|
||||
}
|
||||
// Halt everything upon a critical event flag. Currently hard and soft limits flag this.
|
||||
if (rt_exec & EXEC_CRITICAL_EVENT) {
|
||||
report_feedback_message(MESSAGE_CRITICAL_EVENT);
|
||||
bit_false_atomic(sys.execute,EXEC_RESET); // Disable any existing reset
|
||||
bit_false_atomic(sys.rt_exec_state,EXEC_RESET); // Disable any existing reset
|
||||
do {
|
||||
// Nothing. Block EVERYTHING until user issues reset or power cycles. Hard limits
|
||||
// typically occur while unattended or not paying attention. Gives the user time
|
||||
// to do what is needed before resetting, like killing the incoming stream. The
|
||||
// same could be said about soft limits. While the position is not lost, the incoming
|
||||
// stream could be still engaged and cause a serious crash if it continues afterwards.
|
||||
} while (bit_isfalse(sys.execute,EXEC_RESET));
|
||||
|
||||
// Standard alarm event. Only abort during motion qualifies.
|
||||
} else {
|
||||
// Runtime abort command issued during a cycle, feed hold, or homing cycle. Message the
|
||||
// user that position may have been lost and set alarm state to enable the alarm lockout
|
||||
// to indicate the possible severity of the problem.
|
||||
report_alarm_message(ALARM_ABORT_CYCLE);
|
||||
} while (bit_isfalse(sys.rt_exec_state,EXEC_RESET));
|
||||
}
|
||||
bit_false_atomic(sys.execute,(EXEC_ALARM | EXEC_CRIT_EVENT));
|
||||
bit_false_atomic(sys.rt_exec_alarm,0xFF); // Clear all alarm flags
|
||||
}
|
||||
|
||||
// Check amd execute realtime commands
|
||||
rt_exec = sys.rt_exec_state; // Copy volatile sys.rt_exec_state.
|
||||
if (rt_exec) { // Enter only if any bit flag is true
|
||||
// Execute system abort.
|
||||
if (rt_exec & EXEC_RESET) {
|
||||
sys.abort = true; // Only place this is set true.
|
||||
@ -225,7 +227,7 @@ void protocol_execute_runtime()
|
||||
// Execute and serial print status
|
||||
if (rt_exec & EXEC_STATUS_REPORT) {
|
||||
report_realtime_status();
|
||||
bit_false_atomic(sys.execute,EXEC_STATUS_REPORT);
|
||||
bit_false_atomic(sys.rt_exec_state,EXEC_STATUS_REPORT);
|
||||
}
|
||||
|
||||
// Execute a feed hold with deceleration, only during cycle.
|
||||
@ -238,7 +240,7 @@ void protocol_execute_runtime()
|
||||
st_prep_buffer();
|
||||
sys.auto_start = false; // Disable planner auto start upon feed hold.
|
||||
}
|
||||
bit_false_atomic(sys.execute,EXEC_FEED_HOLD);
|
||||
bit_false_atomic(sys.rt_exec_state,EXEC_FEED_HOLD);
|
||||
}
|
||||
|
||||
// Execute a cycle start by starting the stepper interrupt begin executing the blocks in queue.
|
||||
@ -253,24 +255,23 @@ void protocol_execute_runtime()
|
||||
sys.auto_start = false; // Reset auto start per settings.
|
||||
}
|
||||
}
|
||||
bit_false_atomic(sys.execute,EXEC_CYCLE_START);
|
||||
bit_false_atomic(sys.rt_exec_state,EXEC_CYCLE_START);
|
||||
}
|
||||
|
||||
// Reinitializes the cycle plan and stepper system after a feed hold for a resume. Called by
|
||||
// runtime command execution in the main program, ensuring that the planner re-plans safely.
|
||||
// realtime command execution in the main program, ensuring that the planner re-plans safely.
|
||||
// NOTE: Bresenham algorithm variables are still maintained through both the planner and stepper
|
||||
// cycle reinitializations. The stepper path should continue exactly as if nothing has happened.
|
||||
// NOTE: EXEC_CYCLE_STOP is set by the stepper subsystem when a cycle or feed hold completes.
|
||||
if (rt_exec & EXEC_CYCLE_STOP) {
|
||||
if ( plan_get_current_block() ) { sys.state = STATE_QUEUED; }
|
||||
else { sys.state = STATE_IDLE; }
|
||||
bit_false_atomic(sys.execute,EXEC_CYCLE_STOP);
|
||||
bit_false_atomic(sys.rt_exec_state,EXEC_CYCLE_STOP);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Overrides flag byte (sys.override) and execution should be installed here, since they
|
||||
// are runtime and require a direct and controlled interface to the main stepper program.
|
||||
// are realtime and require a direct and controlled interface to the main stepper program.
|
||||
|
||||
// Reload step segment buffer
|
||||
if (sys.state & (STATE_CYCLE | STATE_HOLD | STATE_HOMING)) { st_prep_buffer(); }
|
||||
@ -287,7 +288,7 @@ void protocol_buffer_synchronize()
|
||||
// Check and set auto start to resume cycle after synchronize and caller completes.
|
||||
if (sys.state == STATE_CYCLE) { sys.auto_start = true; }
|
||||
while (plan_get_current_block() || (sys.state == STATE_CYCLE)) {
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -303,4 +304,4 @@ void protocol_buffer_synchronize()
|
||||
// NOTE: This function is called from the main loop and mc_line() only and executes when one of
|
||||
// two conditions exist respectively: There are no more blocks sent (i.e. streaming is finished,
|
||||
// single commands), or the planner buffer is full and ready to go.
|
||||
void protocol_auto_cycle_start() { if (sys.auto_start) { bit_true_atomic(sys.execute, EXEC_CYCLE_START); } }
|
||||
void protocol_auto_cycle_start() { if (sys.auto_start) { bit_true_atomic(sys.rt_exec_state, EXEC_CYCLE_START); } }
|
||||
|
@ -2,7 +2,7 @@
|
||||
protocol.h - controls Grbl execution protocol and procedures
|
||||
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
|
||||
@ -41,8 +41,8 @@
|
||||
// them as they complete. It is also responsible for finishing the initialization procedures.
|
||||
void protocol_main_loop();
|
||||
|
||||
// Checks and executes a runtime command at various stop points in main program
|
||||
void protocol_execute_runtime();
|
||||
// Checks and executes a realtime command at various stop points in main program
|
||||
void protocol_execute_realtime();
|
||||
|
||||
// Notify the stepper subsystem to start executing the g-code program in buffer.
|
||||
// void protocol_cycle_start();
|
||||
|
17
report.c
17
report.c
@ -2,7 +2,7 @@
|
||||
report.c - reporting and messaging 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
|
||||
@ -97,8 +97,10 @@ void report_alarm_message(int8_t alarm_code)
|
||||
{
|
||||
printPgmString(PSTR("ALARM: "));
|
||||
switch (alarm_code) {
|
||||
case ALARM_LIMIT_ERROR:
|
||||
printPgmString(PSTR("Hard/soft limit")); break;
|
||||
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:
|
||||
@ -232,7 +234,7 @@ void report_probe_parameters()
|
||||
// Report in terms of machine position.
|
||||
printPgmString(PSTR("[PRB:"));
|
||||
for (i=0; i< N_AXIS; i++) {
|
||||
print_position[i] = sys.probe_position[i]/settings.steps_per_mm[i];
|
||||
print_position[i] = system_convert_axis_steps_to_mpos(sys.probe_position,i);
|
||||
printFloat_CoordValue(print_position[i]);
|
||||
if (i < (N_AXIS-1)) { printPgmString(PSTR(",")); }
|
||||
}
|
||||
@ -394,17 +396,12 @@ void report_realtime_status()
|
||||
|
||||
// If reporting a position, convert the current step count (current_position) to millimeters.
|
||||
if (bit_istrue(settings.status_report_mask,(BITFLAG_RT_STATUS_MACHINE_POSITION | BITFLAG_RT_STATUS_WORK_POSITION))) {
|
||||
for (i=0; i< N_AXIS; i++) { print_position[i] = current_position[i]/settings.steps_per_mm[i]; }
|
||||
system_convert_array_steps_to_mpos(print_position,current_position);
|
||||
}
|
||||
|
||||
// Report machine position
|
||||
if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_MACHINE_POSITION)) {
|
||||
printPgmString(PSTR(",MPos:"));
|
||||
// print_position[X_AXIS] = 0.5*current_position[X_AXIS]/settings.steps_per_mm[X_AXIS];
|
||||
// print_position[Z_AXIS] = 0.5*current_position[Y_AXIS]/settings.steps_per_mm[Y_AXIS];
|
||||
// print_position[Y_AXIS] = print_position[X_AXIS]-print_position[Z_AXIS]);
|
||||
// print_position[X_AXIS] -= print_position[Z_AXIS];
|
||||
// print_position[Z_AXIS] = current_position[Z_AXIS]/settings.steps_per_mm[Z_AXIS];
|
||||
for (i=0; i< N_AXIS; i++) {
|
||||
printFloat_CoordValue(print_position[i]);
|
||||
if (i < (N_AXIS-1)) { printPgmString(PSTR(",")); }
|
||||
|
9
report.h
9
report.h
@ -2,7 +2,7 @@
|
||||
report.h - reporting and messaging 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
|
||||
@ -54,9 +54,10 @@
|
||||
#define STATUS_GCODE_G43_DYNAMIC_AXIS_ERROR 37
|
||||
|
||||
// Define Grbl alarm codes. Less than zero to distinguish alarm error from status error.
|
||||
#define ALARM_LIMIT_ERROR -1
|
||||
#define ALARM_ABORT_CYCLE -2
|
||||
#define ALARM_PROBE_FAIL -3
|
||||
#define ALARM_HARD_LIMIT_ERROR -1
|
||||
#define ALARM_SOFT_LIMIT_ERROR -2
|
||||
#define ALARM_ABORT_CYCLE -3
|
||||
#define ALARM_PROBE_FAIL -4
|
||||
|
||||
// Define Grbl feedback message codes.
|
||||
#define MESSAGE_CRITICAL_EVENT 1
|
||||
|
14
serial.c
14
serial.c
@ -2,7 +2,7 @@
|
||||
serial.c - Low level functions for sending and recieving bytes via the serial port
|
||||
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
|
||||
@ -98,7 +98,7 @@ void serial_write(uint8_t data) {
|
||||
// Wait until there is space in the buffer
|
||||
while (next_head == serial_tx_buffer_tail) {
|
||||
// TODO: Restructure st_prep_buffer() calls to be executed here during a long print.
|
||||
if (sys.execute & EXEC_RESET) { return; } // Only check for abort to avoid an endless loop.
|
||||
if (sys.rt_exec_state & EXEC_RESET) { return; } // Only check for abort to avoid an endless loop.
|
||||
}
|
||||
|
||||
// Store data and advance head
|
||||
@ -170,12 +170,12 @@ ISR(SERIAL_RX)
|
||||
uint8_t data = UDR0;
|
||||
uint8_t next_head;
|
||||
|
||||
// Pick off runtime command characters directly from the serial stream. These characters are
|
||||
// not passed into the buffer, but these set system state flag bits for runtime execution.
|
||||
// Pick off realtime command characters directly from the serial stream. These characters are
|
||||
// not passed into the buffer, but these set system state flag bits for realtime execution.
|
||||
switch (data) {
|
||||
case CMD_STATUS_REPORT: bit_true_atomic(sys.execute, EXEC_STATUS_REPORT); break; // Set as true
|
||||
case CMD_CYCLE_START: bit_true_atomic(sys.execute, EXEC_CYCLE_START); break; // Set as true
|
||||
case CMD_FEED_HOLD: bit_true_atomic(sys.execute, EXEC_FEED_HOLD); break; // Set as true
|
||||
case CMD_STATUS_REPORT: bit_true_atomic(sys.rt_exec_state, EXEC_STATUS_REPORT); break; // Set as true
|
||||
case CMD_CYCLE_START: bit_true_atomic(sys.rt_exec_state, EXEC_CYCLE_START); break; // Set as true
|
||||
case CMD_FEED_HOLD: bit_true_atomic(sys.rt_exec_state, EXEC_FEED_HOLD); break; // Set as true
|
||||
case CMD_RESET: mc_reset(); break; // Call motion control reset routine.
|
||||
default: // Write character to buffer
|
||||
next_head = serial_rx_buffer_head + 1;
|
||||
|
2
serial.h
2
serial.h
@ -2,7 +2,7 @@
|
||||
serial.c - Low level functions for sending and recieving bytes via the serial port
|
||||
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
|
||||
|
@ -2,7 +2,7 @@
|
||||
settings.c - eeprom configuration handling
|
||||
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
|
||||
@ -110,7 +110,7 @@ void settings_restore_global_settings() {
|
||||
// Helper function to clear the EEPROM space containing parameter data.
|
||||
void settings_clear_parameters() {
|
||||
uint8_t idx;
|
||||
float coord_data[3];
|
||||
float coord_data[N_AXIS];
|
||||
memset(&coord_data, 0, sizeof(coord_data));
|
||||
for (idx=0; idx < SETTING_INDEX_NCOORD; idx++) { settings_write_coord_data(idx, coord_data); }
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
settings.h - eeprom configuration handling
|
||||
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
|
||||
@ -28,8 +28,8 @@
|
||||
#define settings_h
|
||||
|
||||
|
||||
#define GRBL_VERSION "0.9g"
|
||||
#define GRBL_VERSION_BUILD "20140905"
|
||||
#define GRBL_VERSION "0.9h"
|
||||
#define GRBL_VERSION_BUILD "20150114"
|
||||
|
||||
// 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
|
||||
|
@ -2,7 +2,7 @@
|
||||
spindle_control.c - 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
|
||||
@ -60,22 +60,16 @@ void spindle_stop()
|
||||
}
|
||||
|
||||
|
||||
void spindle_run(uint8_t direction, float rpm)
|
||||
void spindle_set_state(uint8_t state, float rpm)
|
||||
{
|
||||
if (sys.state == STATE_CHECK_MODE) { return; }
|
||||
|
||||
// Empty planner buffer to ensure spindle is set when programmed.
|
||||
protocol_auto_cycle_start(); //temp fix for M3 lockup
|
||||
protocol_buffer_synchronize();
|
||||
|
||||
// Halt or set spindle direction and rpm.
|
||||
if (direction == SPINDLE_DISABLE) {
|
||||
if (state == SPINDLE_DISABLE) {
|
||||
|
||||
spindle_stop();
|
||||
|
||||
} else {
|
||||
|
||||
if (direction == SPINDLE_ENABLE_CW) {
|
||||
if (state == SPINDLE_ENABLE_CW) {
|
||||
SPINDLE_DIRECTION_PORT &= ~(1<<SPINDLE_DIRECTION_BIT);
|
||||
} else {
|
||||
SPINDLE_DIRECTION_PORT |= (1<<SPINDLE_DIRECTION_BIT);
|
||||
@ -83,21 +77,30 @@ void spindle_run(uint8_t direction, float rpm)
|
||||
|
||||
#ifdef VARIABLE_SPINDLE
|
||||
// TODO: Install the optional capability for frequency-based output for servos.
|
||||
#define SPINDLE_RPM_RANGE (SPINDLE_MAX_RPM-SPINDLE_MIN_RPM)
|
||||
#ifdef CPU_MAP_ATMEGA2560
|
||||
TCCRA_REGISTER = (1<<COMB_BIT) | (1<<WAVE1_REGISTER) | (1<<WAVE0_REGISTER);
|
||||
TCCRB_REGISTER = (TCCRB_REGISTER & 0b11111000) | 0x02 | (1<<WAVE2_REGISTER) | (1<<WAVE3_REGISTER); // set to 1/8 Prescaler
|
||||
OCR4A = 0xFFFF; // set the top 16bit value
|
||||
uint16_t current_pwm;
|
||||
#else
|
||||
TCCRA_REGISTER = (1<<COMB_BIT) | (1<<WAVE1_REGISTER) | (1<<WAVE0_REGISTER);
|
||||
TCCRB_REGISTER = (TCCRB_REGISTER & 0b11111000) | 0x02; // set to 1/8 Prescaler
|
||||
uint8_t current_pwm;
|
||||
#endif
|
||||
|
||||
#define SPINDLE_RPM_RANGE (SPINDLE_MAX_RPM-SPINDLE_MIN_RPM)
|
||||
if ( rpm < SPINDLE_MIN_RPM ) { rpm = 0; }
|
||||
else {
|
||||
rpm -= SPINDLE_MIN_RPM;
|
||||
if ( rpm > 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<<SPINDLE_ENABLE_BIT);
|
||||
#endif
|
||||
#else
|
||||
@ -106,3 +109,11 @@ void spindle_run(uint8_t direction, float rpm)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void spindle_run(uint8_t state, float rpm)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
spindle_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
|
||||
@ -34,6 +34,8 @@ void spindle_init();
|
||||
// Sets spindle direction and spindle rpm via PWM, if enabled.
|
||||
void spindle_run(uint8_t direction, float rpm);
|
||||
|
||||
void spindle_set_state(uint8_t state, float rpm);
|
||||
|
||||
// Kills spindle.
|
||||
void spindle_stop();
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
stepper.c - stepper motor driver: executes motion plans using stepper motors
|
||||
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
|
||||
@ -228,7 +228,7 @@ void st_go_idle()
|
||||
|
||||
// Set stepper driver idle state, disabled or enabled, depending on settings and circumstances.
|
||||
bool pin_state = false; // Keep enabled.
|
||||
if (((settings.stepper_idle_lock_time != 0xff) || bit_istrue(sys.execute,EXEC_ALARM)) && sys.state != STATE_HOMING) {
|
||||
if (((settings.stepper_idle_lock_time != 0xff) || sys.rt_exec_alarm) && sys.state != STATE_HOMING) {
|
||||
// Force stepper dwell to lock axes for a defined amount of time to ensure the axes come to a complete
|
||||
// stop and not drift from residual inertial forces at the end of the last movement.
|
||||
delay_ms(settings.stepper_idle_lock_time);
|
||||
@ -351,7 +351,7 @@ ISR(TIMER1_COMPA_vect)
|
||||
} else {
|
||||
// Segment buffer empty. Shutdown.
|
||||
st_go_idle();
|
||||
bit_true_atomic(sys.execute,EXEC_CYCLE_STOP); // Flag main program for cycle end
|
||||
bit_true_atomic(sys.rt_exec_state,EXEC_CYCLE_STOP); // Flag main program for cycle end
|
||||
return; // Nothing to do but exit.
|
||||
}
|
||||
}
|
||||
@ -846,7 +846,7 @@ void st_prep_buffer()
|
||||
}
|
||||
|
||||
|
||||
// Called by runtime status reporting to fetch the current speed being executed. This value
|
||||
// Called by realtime status reporting to fetch the current speed being executed. This value
|
||||
// however is not exactly the current speed, but the speed computed in the last step segment
|
||||
// in the segment buffer. It will always be behind by up to the number of segment blocks (-1)
|
||||
// divided by the ACCELERATION TICKS PER SECOND in seconds.
|
||||
|
@ -2,7 +2,7 @@
|
||||
stepper.h - stepper motor driver: executes motion plans of planner.c using the stepper motors
|
||||
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
|
||||
@ -34,7 +34,7 @@
|
||||
// Initialize and setup the stepper motor subsystem
|
||||
void stepper_init();
|
||||
|
||||
// Enable steppers, but cycle does not start unless called by motion control or runtime command.
|
||||
// Enable steppers, but cycle does not start unless called by motion control or realtime command.
|
||||
void st_wake_up();
|
||||
|
||||
// Immediately disables steppers
|
||||
@ -46,13 +46,13 @@ void st_generate_step_dir_invert_masks();
|
||||
// Reset the stepper subsystem variables
|
||||
void st_reset();
|
||||
|
||||
// Reloads step segment buffer. Called continuously by runtime execution system.
|
||||
// Reloads step segment buffer. Called continuously by realtime execution system.
|
||||
void st_prep_buffer();
|
||||
|
||||
// Called by planner_recalculate() when the executing block is updated by the new plan.
|
||||
void st_update_plan_block_parameters();
|
||||
|
||||
// Called by runtime status reporting if realtime rate reporting is enabled in config.h.
|
||||
// Called by realtime status reporting if realtime rate reporting is enabled in config.h.
|
||||
#ifdef REPORT_REALTIME_RATE
|
||||
float st_get_realtime_rate();
|
||||
#endif
|
||||
|
47
system.c
47
system.c
@ -2,7 +2,7 @@
|
||||
system.c - Handles system level commands and real-time processes
|
||||
Part of Grbl v0.9
|
||||
|
||||
Copyright (c) 2014 Sungeun K. Jeon
|
||||
Copyright (c) 2014-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
|
||||
@ -20,8 +20,10 @@
|
||||
|
||||
#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"
|
||||
|
||||
@ -36,8 +38,8 @@ void system_init()
|
||||
|
||||
|
||||
// Pin change interrupt for pin-out commands, i.e. cycle start, feed hold, and reset. Sets
|
||||
// only the runtime command execute variable to have the main program execute these when
|
||||
// its ready. This works exactly like the character-based runtime commands when picked off
|
||||
// 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)
|
||||
{
|
||||
@ -46,9 +48,9 @@ ISR(PINOUT_INT_vect)
|
||||
if (bit_isfalse(PINOUT_PIN,bit(PIN_RESET))) {
|
||||
mc_reset();
|
||||
} else if (bit_isfalse(PINOUT_PIN,bit(PIN_FEED_HOLD))) {
|
||||
bit_true(sys.execute, EXEC_FEED_HOLD);
|
||||
bit_true(sys.rt_exec_state, EXEC_FEED_HOLD);
|
||||
} else if (bit_isfalse(PINOUT_PIN,bit(PIN_CYCLE_START))) {
|
||||
bit_true(sys.execute, EXEC_CYCLE_START);
|
||||
bit_true(sys.rt_exec_state, EXEC_CYCLE_START);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -74,7 +76,7 @@ void system_execute_startup(char *line)
|
||||
// Directs and executes one line of formatted input from protocol_process. While mostly
|
||||
// incoming streaming g-code blocks, this also executes Grbl internal commands, such as
|
||||
// settings, initiating the homing cycle, and toggling switch states. This differs from
|
||||
// the runtime command module by being susceptible to when Grbl is ready to execute the
|
||||
// the realtime command module by being susceptible to when Grbl is ready to execute the
|
||||
// next line during a cycle, so for switches like block delete, the switch only effects
|
||||
// the lines that are processed afterward, not necessarily real-time during a cycle,
|
||||
// since there are motions already stored in the buffer. However, this 'lag' should not
|
||||
@ -119,7 +121,7 @@ uint8_t system_execute_line(char *line)
|
||||
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 runtime commands except for e-stop. The jogging function is intended to
|
||||
// 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
|
||||
@ -139,9 +141,14 @@ uint8_t system_execute_line(char *line)
|
||||
break;
|
||||
case 'H' : // Perform homing cycle [IDLE/ALARM]
|
||||
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.
|
||||
mc_homing_cycle();
|
||||
if (!sys.abort) { system_execute_startup(line); } // Execute startup scripts after successful homing.
|
||||
if (!sys.abort) { // Execute startup scripts after successful homing.
|
||||
sys.state = STATE_IDLE; // Set to IDLE when complete.
|
||||
st_go_idle(); // Set steppers to the settings idle state before returning.
|
||||
system_execute_startup(line);
|
||||
}
|
||||
} else { return(STATUS_SETTING_DISABLED); }
|
||||
break;
|
||||
case 'I' : // Print or store build info. [IDLE/ALARM]
|
||||
@ -197,3 +204,27 @@ uint8_t system_execute_line(char *line)
|
||||
}
|
||||
return(STATUS_OK); // If '$' command makes it to here, then everything's ok.
|
||||
}
|
||||
|
||||
|
||||
float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx)
|
||||
{
|
||||
#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]);
|
||||
}
|
||||
#else
|
||||
return((float)steps[idx]/settings.steps_per_mm[idx]);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void system_convert_array_steps_to_mpos(float *position, int32_t *steps)
|
||||
{
|
||||
uint8_t idx;
|
||||
for (idx=0; idx<N_AXIS; idx++) {
|
||||
position[idx] = system_convert_axis_steps_to_mpos(steps, idx);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
36
system.h
36
system.h
@ -2,7 +2,7 @@
|
||||
system.h - Header for system level commands and real-time processes
|
||||
Part of Grbl v0.9
|
||||
|
||||
Copyright (c) 2014 Sungeun K. Jeon
|
||||
Copyright (c) 2014-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
|
||||
@ -41,19 +41,26 @@
|
||||
#include "nuts_bolts.h"
|
||||
|
||||
|
||||
// Define system executor bit map. Used internally by runtime protocol as runtime command flags,
|
||||
// which notifies the main program to execute the specified runtime command asynchronously.
|
||||
// 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.
|
||||
// NOTE: The system executor uses an unsigned 8-bit volatile variable (8 flag limit.) The default
|
||||
// flags are always false, so the runtime protocol only needs to check for a non-zero value to
|
||||
// know when there is a runtime command to execute.
|
||||
// flags are always false, so the realtime protocol only needs to check for a non-zero value to
|
||||
// know when there is a realtime command to execute.
|
||||
#define EXEC_STATUS_REPORT bit(0) // bitmask 00000001
|
||||
#define EXEC_CYCLE_START bit(1) // bitmask 00000010
|
||||
#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_ALARM bit(5) // bitmask 00100000
|
||||
#define EXEC_CRIT_EVENT bit(6) // bitmask 01000000
|
||||
// #define bit(7) // bitmask 10000000
|
||||
|
||||
// Alarm executor bit map.
|
||||
// NOTE: EXEC_CRITICAL_EVENT is an optional flag that must be set with an alarm flag. When enabled,
|
||||
// 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 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
|
||||
@ -72,7 +79,9 @@
|
||||
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.
|
||||
volatile uint8_t execute; // Global system runtime executor bitflag variable. See EXEC bitmasks.
|
||||
|
||||
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.
|
||||
@ -92,10 +101,13 @@ void system_init();
|
||||
// Executes an internal system command, defined as a string starting with a '$'
|
||||
uint8_t system_execute_line(char *line);
|
||||
|
||||
// Checks and executes a runtime command at various stop points in main program
|
||||
void system_execute_runtime();
|
||||
|
||||
// Execute the startup script lines stored in EEPROM upon initialization
|
||||
void system_execute_startup(char *line);
|
||||
|
||||
// Returns machine position of axis 'idx'. Must be sent a 'step' array.
|
||||
float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx);
|
||||
|
||||
// Updates a machine 'position' array based on the 'step' array sent.
|
||||
void system_convert_array_steps_to_mpos(float *position, int32_t *steps);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,773 +0,0 @@
|
||||
(ShapeOko2 "Hello World" test file)
|
||||
(Set up sheet of paper landscape, long edge on X-axis)
|
||||
(Starting location around the lower[-y] left[-x] corner)
|
||||
|
||||
(originally Generated by PartKam Version 0.05)
|
||||
|
||||
G20 G90 (remove G40)
|
||||
|
||||
(write the words)
|
||||
G0 Z0.125
|
||||
(remove x)
|
||||
G17
|
||||
|
||||
G0 X0.435 Y0.4042
|
||||
G1 Z-0.01 F10
|
||||
G3 X0.4557 Y0.4046 I0 J0.4533 F40
|
||||
G3 X0.4728 Y0.4059 I-0.0142 J0.3117
|
||||
G3 X0.4898 Y0.4082 I-0.0257 J0.2542
|
||||
G3 X0.5034 Y0.4111 I-0.028 J0.1653
|
||||
G3 X0.5168 Y0.415 I-0.0472 J0.1844
|
||||
G3 X0.5278 Y0.4192 I-0.0435 J0.1296
|
||||
G3 X0.5383 Y0.4245 I-0.0462 J0.1062
|
||||
G3 X0.5468 Y0.4299 I-0.0415 J0.0739
|
||||
G3 X0.5545 Y0.4363 I-0.0474 J0.0649
|
||||
G3 X0.5606 Y0.4429 I-0.0441 J0.0468
|
||||
G3 X0.5656 Y0.4503 I-0.0464 J0.0371
|
||||
G3 X0.5694 Y0.4582 I-0.0481 J0.0278
|
||||
G3 X0.5721 Y0.4664 I-0.0805 J0.031
|
||||
G3 X0.5741 Y0.4754 I-0.093 J0.0254
|
||||
G3 X0.5753 Y0.4846 I-0.1022 J0.0176
|
||||
G3 X0.5757 Y0.4946 I-0.1224 J0.01
|
||||
G3 X0.5731 Y0.5153 I-0.083 J0
|
||||
G3 X0.5656 Y0.5337 I-0.0731 J-0.0188
|
||||
G3 X0.5537 Y0.5498 I-0.072 J-0.0408
|
||||
G3 X0.5355 Y0.5656 I-0.0876 J-0.083
|
||||
G3 X0.5146 Y0.5784 I-0.1178 J-0.1676
|
||||
G3 X0.4808 Y0.5949 I-0.2293 J-0.4268
|
||||
G3 X0.4459 Y0.6092 I-0.282 J-0.6397
|
||||
G3 X0.3973 Y0.6265 I-0.4624 J-1.2235
|
||||
G2 X0.376 Y0.6343 I0.3353 J0.9488
|
||||
G2 X0.3546 Y0.6427 I0.3684 J0.9724
|
||||
G2 X0.3333 Y0.6515 I0.3967 J0.9808
|
||||
G2 X0.3119 Y0.661 I0.4333 J1.0077
|
||||
G2 X0.2909 Y0.6715 I0.1396 J0.3066
|
||||
G2 X0.2714 Y0.683 I0.1507 J0.2779
|
||||
G2 X0.2527 Y0.6959 I0.1666 J0.2606
|
||||
G2 X0.2353 Y0.71 I0.1811 J0.2422
|
||||
G2 X0.2191 Y0.7255 I0.1487 J0.1708
|
||||
G2 X0.2045 Y0.7427 I0.1668 J0.1572
|
||||
G2 X0.1916 Y0.7611 I0.1861 J0.1436
|
||||
G2 X0.18 Y0.7816 I0.2168 J0.1363
|
||||
G2 X0.1709 Y0.8032 I0.1508 J0.0765
|
||||
G2 X0.164 Y0.8282 I0.1965 J0.0675
|
||||
G2 X0.1601 Y0.854 I0.2316 J0.0483
|
||||
G2 X0.1587 Y0.884 I0.3133 J0.03
|
||||
G2 X0.1601 Y0.914 I0.3058 J0
|
||||
G2 X0.1643 Y0.9413 I0.2576 J-0.0254
|
||||
G2 X0.1715 Y0.968 I0.2377 J-0.0494
|
||||
G2 X0.1813 Y0.9926 I0.2132 J-0.0704
|
||||
G2 X0.1938 Y1.016 I0.2171 J-0.1015
|
||||
G2 X0.2086 Y1.0374 I0.1951 J-0.1191
|
||||
G2 X0.2257 Y1.0569 I0.1807 J-0.1407
|
||||
G2 X0.2453 Y1.0749 I0.1727 J-0.1691
|
||||
G2 X0.2668 Y1.0906 I0.1588 J-0.1942
|
||||
G2 X0.2912 Y1.1049 I0.1534 J-0.2346
|
||||
G2 X0.3168 Y1.1167 I0.1391 J-0.2681
|
||||
G2 X0.3458 Y1.127 I0.1352 J-0.3335
|
||||
G2 X0.3756 Y1.1348 I0.1068 J-0.3459
|
||||
G2 X0.4086 Y1.1407 I0.0911 J-0.4184
|
||||
G2 X0.442 Y1.144 I0.0638 J-0.4657
|
||||
G2 X0.4789 Y1.1452 I0.037 J-0.5706
|
||||
G2 X0.5228 Y1.144 I0 J-0.7643
|
||||
G2 X0.5609 Y1.1405 I-0.0333 J-0.5787
|
||||
G2 X0.5986 Y1.1344 I-0.062 J-0.5001
|
||||
G2 X0.6309 Y1.1264 I-0.0758 J-0.3755
|
||||
G2 X0.6627 Y1.1163 I-0.2335 J-0.7931
|
||||
G2 X0.6893 Y1.1066 I-0.191 J-0.5638
|
||||
G2 X0.7154 Y1.0955 I-0.1827 J-0.4653
|
||||
G2 X0.7364 Y1.0849 I-0.1447 J-0.3148
|
||||
G1 X0.6799 Y0.9304
|
||||
G3 X0.6615 Y0.9394 I-0.2077 J-0.4011
|
||||
G3 X0.6414 Y0.9482 I-0.2158 J-0.4675
|
||||
G3 X0.621 Y0.9561 I-0.2093 J-0.5093
|
||||
G3 X0.5989 Y0.9637 I-0.2164 J-0.5924
|
||||
G3 X0.5764 Y0.9698 I-0.0747 J-0.2309
|
||||
G3 X0.5498 Y0.9745 I-0.0698 J-0.3171
|
||||
G3 X0.5228 Y0.9772 I-0.0502 J-0.3738
|
||||
G3 X0.4915 Y0.9782 I-0.0314 J-0.5063
|
||||
G3 X0.4565 Y0.9767 I0 J-0.4369
|
||||
G3 X0.4311 Y0.9733 I0.0187 J-0.2329
|
||||
G3 X0.4065 Y0.9666 I0.0312 J-0.1619
|
||||
G3 X0.3904 Y0.9587 I0.0277 J-0.0771
|
||||
G3 X0.3767 Y0.9474 I0.0374 J-0.0591
|
||||
G3 X0.3673 Y0.9341 I0.0432 J-0.0405
|
||||
G3 X0.3618 Y0.9186 I0.0563 J-0.029
|
||||
G3 X0.3596 Y0.899 I0.0892 J-0.0196
|
||||
G3 X0.3604 Y0.8872 I0.093 J0
|
||||
G3 X0.3625 Y0.8771 I0.0704 J0.009
|
||||
G3 X0.366 Y0.8674 I0.0617 J0.0173
|
||||
G3 X0.3709 Y0.8588 I0.0525 J0.0244
|
||||
G3 X0.377 Y0.851 I0.0702 J0.0485
|
||||
G3 X0.3846 Y0.8433 I0.0772 J0.0678
|
||||
G3 X0.3929 Y0.8363 I0.0778 J0.0845
|
||||
G3 X0.403 Y0.8293 I0.0886 J0.1165
|
||||
G3 X0.4135 Y0.823 I0.1229 J0.1933
|
||||
G3 X0.4253 Y0.8168 I0.1326 J0.2355
|
||||
G3 X0.4373 Y0.8111 I0.1314 J0.2629
|
||||
G3 X0.4507 Y0.8055 I0.1413 J0.3181
|
||||
G3 X0.4642 Y0.8002 I0.4349 J1.1
|
||||
G3 X0.4791 Y0.7946 I0.5053 J1.3254
|
||||
G3 X0.4941 Y0.7892 I0.5351 J1.4522
|
||||
G3 X0.5104 Y0.7835 I0.615 J1.7234
|
||||
G2 X0.5441 Y0.7706 I-0.62 J-1.6745
|
||||
G2 X0.5738 Y0.7585 I-0.5126 J-1.3027
|
||||
G2 X0.6031 Y0.7457 I-0.4768 J-1.135
|
||||
G2 X0.6284 Y0.7339 I-0.3858 J-0.8553
|
||||
G2 X0.653 Y0.7208 I-0.1756 J-0.3603
|
||||
G2 X0.6744 Y0.7073 I-0.164 J-0.2844
|
||||
G2 X0.6946 Y0.6922 I-0.1689 J-0.2468
|
||||
G2 X0.7119 Y0.6767 I-0.1605 J-0.1966
|
||||
G2 X0.7276 Y0.6596 I-0.1493 J-0.1521
|
||||
G2 X0.741 Y0.6412 I-0.1581 J-0.1293
|
||||
G2 X0.7522 Y0.6215 I-0.172 J-0.1113
|
||||
G2 X0.7615 Y0.6001 I-0.1936 J-0.0968
|
||||
G2 X0.7685 Y0.5778 I-0.2008 J-0.0746
|
||||
G2 X0.7738 Y0.5514 I-0.2755 J-0.0693
|
||||
G2 X0.7768 Y0.5247 I-0.3264 J-0.0499
|
||||
G2 X0.7779 Y0.4934 I-0.4455 J-0.0313
|
||||
G2 X0.772 Y0.4337 I-0.3082 J0
|
||||
G2 X0.7565 Y0.3852 I-0.2183 J0.0431
|
||||
G2 X0.7301 Y0.3418 I-0.1887 J0.0852
|
||||
G2 X0.6925 Y0.3043 I-0.1784 J0.1413
|
||||
G2 X0.647 Y0.2762 I-0.146 J0.1856
|
||||
G2 X0.5854 Y0.2539 I-0.1514 J0.3216
|
||||
G2 X0.5204 Y0.2419 I-0.1159 J0.4443
|
||||
G2 X0.435 Y0.2371 I-0.0854 J0.7648
|
||||
G2 X0.4061 Y0.2376 I0 J0.919
|
||||
G2 X0.38 Y0.2388 I0.0236 J0.75
|
||||
G2 X0.354 Y0.2411 I0.0448 J0.6746
|
||||
G2 X0.3307 Y0.244 I0.0572 J0.5433
|
||||
G2 X0.3075 Y0.2478 I0.1319 J0.886
|
||||
G2 X0.2869 Y0.2517 I0.1238 J0.7045
|
||||
G2 X0.2664 Y0.2563 I0.1284 J0.6229
|
||||
G2 X0.2485 Y0.261 I0.1166 J0.4841
|
||||
G2 X0.2307 Y0.2663 I0.1781 J0.6347
|
||||
G2 X0.2152 Y0.2714 I0.1505 J0.4834
|
||||
G2 X0.1999 Y0.277 I0.1443 J0.4161
|
||||
G2 X0.1869 Y0.2823 I0.1191 J0.3062
|
||||
G2 X0.1741 Y0.2881 I0.2781 J0.6336
|
||||
G2 X0.1632 Y0.2933 I0.2146 J0.4632
|
||||
G2 X0.1524 Y0.2988 I0.1915 J0.3889
|
||||
G2 X0.1436 Y0.3037 I0.1422 J0.2695
|
||||
G1 X0.1988 Y0.4594
|
||||
G3 X0.2186 Y0.4494 I0.1622 J0.2959
|
||||
G3 X0.2423 Y0.4392 I0.1933 J0.4152
|
||||
G3 X0.2666 Y0.4302 I0.1967 J0.4934
|
||||
G3 X0.2949 Y0.4211 I0.2292 J0.6675
|
||||
G3 X0.3238 Y0.414 I0.0929 J0.313
|
||||
G3 X0.3585 Y0.4084 I0.0897 J0.4486
|
||||
G3 X0.3936 Y0.4053 I0.065 J0.537
|
||||
G3 X0.435 Y0.4042 I0.0414 J0.7464
|
||||
G0 Z0.125
|
||||
G0 X1.4536 Y1.1251
|
||||
G1 Z-0.01 F10
|
||||
G1 X1.6496 Y1.1251 F40
|
||||
G1 X1.6496 Y0.2547
|
||||
G1 X1.4536 Y0.2547
|
||||
G1 X1.4536 Y0.624
|
||||
G1 X1.1246 Y0.624
|
||||
G1 X1.1246 Y0.2547
|
||||
G1 X0.9286 Y0.2547
|
||||
G1 X0.9286 Y1.1251
|
||||
G1 X1.1246 Y1.1251
|
||||
G1 X1.1246 Y0.7923
|
||||
G1 X1.4536 Y0.7923
|
||||
G1 X1.4536 Y1.1251
|
||||
G0 Z0.125
|
||||
G0 X2.4338 Y0.2547
|
||||
G1 Z-0.01 F10
|
||||
G1 X2.403 Y0.3477 F40
|
||||
G1 X2.3698 Y0.4431
|
||||
G1 X2.0306 Y0.4431
|
||||
G1 X1.9973 Y0.3477
|
||||
G1 X1.9666 Y0.2547
|
||||
G1 X1.7631 Y0.2547
|
||||
G2 X1.7877 Y0.325 I17.8599 J-6.2193
|
||||
G2 X1.8108 Y0.39 I15.3154 J-5.401
|
||||
G2 X1.8342 Y0.455 I14.1288 J-5.0502
|
||||
G2 X1.856 Y0.5147 I11.9637 J-4.3385
|
||||
G2 X1.8782 Y0.5743 I9.7422 J-3.588
|
||||
G2 X1.8995 Y0.6306 I8.7097 J-3.2684
|
||||
G2 X1.9212 Y0.6867 I8.2125 J-3.1426
|
||||
G2 X1.9421 Y0.7395 I7.2956 J-2.8491
|
||||
G2 X1.9633 Y0.7922 I8.4224 J-3.3598
|
||||
G2 X1.9838 Y0.8424 I7.6529 J-3.1085
|
||||
G2 X2.0047 Y0.8924 I7.277 J-3.0116
|
||||
G2 X2.025 Y0.9399 I6.5821 J-2.7772
|
||||
G2 X2.0457 Y0.9872 I4.2002 J-1.8081
|
||||
G2 X2.0666 Y1.0336 I4.0692 J-1.8064
|
||||
G2 X2.0881 Y1.0798 I3.9952 J-1.8286
|
||||
G2 X2.1098 Y1.1251 I3.8717 J-1.8266
|
||||
G1 X2.2969 Y1.1251
|
||||
G2 X2.3181 Y1.0798 I-6.0675 J-2.8652
|
||||
G2 X2.3393 Y1.0336 I-6.3027 J-2.919
|
||||
G2 X2.3602 Y0.9872 I-6.4339 J-2.9227
|
||||
G2 X2.381 Y0.9399 I-6.6806 J-2.977
|
||||
G2 X2.4016 Y0.8924 I-5.4185 J-2.3686
|
||||
G2 X2.4227 Y0.8424 I-5.9798 J-2.5519
|
||||
G2 X2.4433 Y0.7922 I-6.2861 J-2.6208
|
||||
G2 X2.4646 Y0.7395 I-6.9077 J-2.8155
|
||||
G2 X2.4854 Y0.6867 I-7.3628 J-2.9356
|
||||
G2 X2.5071 Y0.6306 I-8.2907 J-3.237
|
||||
G2 X2.5284 Y0.5743 I-8.7947 J-3.3654
|
||||
G2 X2.5506 Y0.5147 I-9.8397 J-3.6933
|
||||
G2 X2.5724 Y0.455 I-11.8601 J-4.3698
|
||||
G2 X2.5958 Y0.39 I-14.0105 J-5.0822
|
||||
G2 X2.6189 Y0.325 I-15.1905 J-5.4307
|
||||
G2 X2.6436 Y0.2547 I-17.7191 J-6.2494
|
||||
G1 X2.4338 Y0.2547
|
||||
G0 Z0.125
|
||||
G0 X2.1989 Y0.9279
|
||||
G1 Z-0.01 F10
|
||||
G2 X2.1957 Y0.9185 I-0.5641 J0.1881 F40
|
||||
G2 X2.1911 Y0.9056 I-1.0677 J0.3759
|
||||
G2 X2.1863 Y0.8928 I-1.4028 J0.513
|
||||
G2 X2.1801 Y0.8764 I-2.2751 J0.8558
|
||||
G3 X2.1738 Y0.8601 I30.9994 J-11.916
|
||||
G3 X2.1666 Y0.8413 I41.2401 J-15.8275
|
||||
G3 X2.1594 Y0.8224 I47.1201 J-18.0595
|
||||
G3 X2.1512 Y0.8011 I60.4881 J-23.1553
|
||||
G3 X2.143 Y0.7797 I19.8859 J-7.6046
|
||||
G3 X2.1341 Y0.7562 I24.1414 J-9.2022
|
||||
G3 X2.1251 Y0.7326 I26.4832 J-10.0653
|
||||
G3 X2.1154 Y0.7069 I31.5951 J-11.976
|
||||
G3 X2.1057 Y0.6811 I4.794 J-1.8127
|
||||
G3 X2.0958 Y0.6541 I5.244 J-1.9507
|
||||
G3 X2.086 Y0.6271 I5.4846 J-2.0082
|
||||
G3 X2.0758 Y0.5988 I5.9771 J-2.1552
|
||||
G1 X2.3233 Y0.5988
|
||||
G3 X2.3132 Y0.6271 I-12.9639 J-4.6057
|
||||
G3 X2.3035 Y0.6541 I-11.8652 J-4.2445
|
||||
G3 X2.2937 Y0.6811 I-11.3354 J-4.0841
|
||||
G3 X2.2843 Y0.7069 I-10.3324 J-3.7506
|
||||
G3 X2.2748 Y0.7326 I-4.3139 J-1.5783
|
||||
G3 X2.266 Y0.7562 I-3.6331 J-1.3538
|
||||
G3 X2.2569 Y0.7797 I-3.3175 J-1.2608
|
||||
G3 X2.2485 Y0.8011 I-2.7503 J-1.0677
|
||||
G2 X2.2401 Y0.8224 I9.4214 J3.7426
|
||||
G2 X2.2327 Y0.8413 I7.3257 J2.8909
|
||||
G2 X2.2253 Y0.8601 I6.4077 J2.5096
|
||||
G2 X2.219 Y0.8764 I4.802 J1.8645
|
||||
G3 X2.2127 Y0.8927 I-7.2811 J-2.7989
|
||||
G3 X2.2077 Y0.9056 I-4.551 J-1.7612
|
||||
G3 X2.2027 Y0.9185 I-3.4837 J-1.3595
|
||||
G3 X2.1989 Y0.9279 I-1.8801 J-0.7417
|
||||
G0 Z0.125
|
||||
G0 X3.0175 Y1.1352
|
||||
G1 Z-0.01 F10
|
||||
G2 X3.1143 Y1.1304 I0 J-0.9783 F40
|
||||
G2 X3.1895 Y1.118 I-0.06 J-0.603
|
||||
G2 X3.2619 Y1.0953 I-0.1063 J-0.4642
|
||||
G2 X3.3164 Y1.0667 I-0.1178 J-0.2911
|
||||
G2 X3.362 Y1.0268 I-0.1208 J-0.184
|
||||
G2 X3.3946 Y0.9764 I-0.1634 J-0.1415
|
||||
G2 X3.4133 Y0.9188 I-0.2268 J-0.1055
|
||||
G2 X3.4207 Y0.8425 I-0.3919 J-0.0763
|
||||
G2 X3.4132 Y0.7656 I-0.4013 J0
|
||||
G2 X3.3943 Y0.7073 I-0.2484 J0.0485
|
||||
G2 X3.3613 Y0.6563 I-0.1992 J0.0927
|
||||
G2 X3.3152 Y0.6158 I-0.1701 J0.147
|
||||
G2 X3.26 Y0.5867 I-0.1755 J0.2656
|
||||
G2 X3.187 Y0.5635 I-0.1806 J0.4426
|
||||
G2 X3.1111 Y0.551 I-0.1365 J0.5905
|
||||
G2 X3.0137 Y0.5461 I-0.0974 J0.969
|
||||
G1 X2.9522 Y0.5461
|
||||
G1 X2.9522 Y0.2547
|
||||
G1 X2.7562 Y0.2547
|
||||
G1 X2.7562 Y1.1126
|
||||
G2 X2.7883 Y1.1183 I0.19 J-0.9718
|
||||
G2 X2.8222 Y1.1232 I0.1732 J-1.0725
|
||||
G2 X2.8561 Y1.1271 I0.1462 J-1.1296
|
||||
G2 X2.8919 Y1.1301 I0.1235 J-1.2476
|
||||
G2 X2.9277 Y1.1324 I0.1789 J-2.5504
|
||||
G2 X2.9591 Y1.1339 I0.1097 J-1.9581
|
||||
G2 X2.9905 Y1.1349 I0.068 J-1.701
|
||||
G2 X3.0175 Y1.1352 I0.027 J-1.257
|
||||
G0 Z0.125
|
||||
G0 X3.03 Y0.9681
|
||||
G1 Z-0.01 F10
|
||||
G1 X2.988 Y0.9669 F40
|
||||
G3 X2.9775 Y0.9662 I0.1375 J-2.2842
|
||||
G3 X2.9686 Y0.9656 I0.1084 J-1.6742
|
||||
G3 X2.9597 Y0.965 I0.0994 J-1.4177
|
||||
G3 X2.9522 Y0.9644 I0.0758 J-0.9911
|
||||
G1 X2.9522 Y0.7131
|
||||
G1 X3.0137 Y0.7131
|
||||
G3 X3.0644 Y0.7151 I0 J0.6562
|
||||
G3 X3.1029 Y0.72 I-0.0297 J0.3827
|
||||
G3 X3.1403 Y0.7294 I-0.051 J0.2826
|
||||
G3 X3.1669 Y0.7408 I-0.0497 J0.1535
|
||||
G3 X3.1895 Y0.7577 I-0.0439 J0.0818
|
||||
G3 X3.2056 Y0.7803 I-0.0644 J0.0629
|
||||
G3 X3.2147 Y0.807 I-0.0959 J0.048
|
||||
G3 X3.2184 Y0.8438 I-0.1813 J0.0368
|
||||
G3 X3.2175 Y0.8619 I-0.1838 J0
|
||||
G3 X3.2151 Y0.877 I-0.1312 J-0.013
|
||||
G3 X3.2109 Y0.8918 I-0.1104 J-0.0241
|
||||
G3 X3.2052 Y0.9041 I-0.0828 J-0.0303
|
||||
G3 X3.1979 Y0.9154 I-0.0877 J-0.0485
|
||||
G3 X3.1892 Y0.9256 I-0.078 J-0.058
|
||||
G3 X3.1793 Y0.9344 I-0.0709 J-0.0697
|
||||
G3 X3.1676 Y0.9424 I-0.0682 J-0.088
|
||||
G3 X3.155 Y0.9489 I-0.0659 J-0.1118
|
||||
G3 X3.1404 Y0.9546 I-0.0654 J-0.1451
|
||||
G3 X3.1253 Y0.959 I-0.0571 J-0.1695
|
||||
G3 X3.1079 Y0.9625 I-0.0538 J-0.2228
|
||||
G3 X3.0903 Y0.9649 I-0.0622 J-0.3868
|
||||
G3 X3.0709 Y0.9667 I-0.0535 J-0.4675
|
||||
G3 X3.0514 Y0.9677 I-0.0373 J-0.514
|
||||
G3 X3.03 Y0.9681 I-0.0213 J-0.6163
|
||||
G0 Z0.125
|
||||
G0 X3.5657 Y0.2547
|
||||
G1 Z-0.01 F10
|
||||
G1 X3.5657 Y1.1251 F40
|
||||
G1 X4.1536 Y1.1251
|
||||
G1 X4.1536 Y0.9606
|
||||
G1 X3.7617 Y0.9606
|
||||
G1 X3.7617 Y0.7898
|
||||
G1 X4.1096 Y0.7898
|
||||
G1 X4.1096 Y0.629
|
||||
G1 X3.7617 Y0.629
|
||||
G1 X3.7617 Y0.4193
|
||||
G1 X4.1825 Y0.4193
|
||||
G1 X4.1825 Y0.2547
|
||||
G1 X3.5657 Y0.2547
|
||||
G0 Z0.125
|
||||
G0 X4.4908 Y0.6905
|
||||
G1 Z-0.01 F10
|
||||
G3 X4.4918 Y0.6586 I0.4971 J0 F40
|
||||
G3 X4.4947 Y0.6296 I0.4109 J0.0265
|
||||
G3 X4.4997 Y0.601 I0.3733 J0.0507
|
||||
G3 X4.5065 Y0.575 I0.3139 J0.0676
|
||||
G3 X4.5154 Y0.5497 I0.3036 J0.0925
|
||||
G3 X4.5256 Y0.5271 I0.2511 J0.1004
|
||||
G3 X4.5379 Y0.5056 I0.2254 J0.1151
|
||||
G3 X4.5517 Y0.4864 I0.1934 J0.124
|
||||
G3 X4.5674 Y0.4689 I0.1636 J0.1303
|
||||
G3 X4.5845 Y0.4536 I0.1398 J0.1398
|
||||
G3 X4.6033 Y0.4405 I0.1224 J0.1548
|
||||
G3 X4.6239 Y0.4293 I0.109 J0.1765
|
||||
G3 X4.6457 Y0.4206 I0.0819 J0.174
|
||||
G3 X4.6698 Y0.4142 I0.0674 J0.205
|
||||
G3 X4.6944 Y0.4105 I0.0471 J0.2296
|
||||
G3 X4.7219 Y0.4092 I0.0275 J0.2849
|
||||
G3 X4.7487 Y0.4105 I0 J0.2758
|
||||
G3 X4.7732 Y0.4142 I-0.0227 J0.2323
|
||||
G3 X4.7971 Y0.4206 I-0.0443 J0.2143
|
||||
G3 X4.8192 Y0.4293 I-0.0629 J0.192
|
||||
G3 X4.8402 Y0.4405 I-0.0881 J0.1899
|
||||
G3 X4.8591 Y0.4536 I-0.1024 J0.1678
|
||||
G3 X4.8763 Y0.4689 I-0.1208 J0.154
|
||||
G3 X4.8921 Y0.4864 I-0.1445 J0.1452
|
||||
G3 X4.9058 Y0.5056 I-0.1798 J0.1433
|
||||
G3 X4.9181 Y0.5271 I-0.2133 J0.1367
|
||||
G3 X4.9284 Y0.5497 I-0.2412 J0.1232
|
||||
G3 X4.9373 Y0.575 I-0.295 J0.1181
|
||||
G3 X4.944 Y0.601 I-0.3069 J0.0937
|
||||
G3 X4.9491 Y0.6296 I-0.3679 J0.0794
|
||||
G3 X4.952 Y0.6586 I-0.4076 J0.0554
|
||||
G3 X4.953 Y0.6905 I-0.4955 J0.032
|
||||
G3 X4.952 Y0.7225 I-0.4983 J0
|
||||
G3 X4.9491 Y0.7516 I-0.4161 J-0.0268
|
||||
G3 X4.944 Y0.7804 I-0.3801 J-0.0514
|
||||
G3 X4.9373 Y0.8067 I-0.3232 J-0.0691
|
||||
G3 X4.9284 Y0.8324 I-0.3076 J-0.0928
|
||||
G3 X4.9181 Y0.8551 I-0.252 J-0.0999
|
||||
G3 X4.9058 Y0.8767 I-0.2249 J-0.1141
|
||||
G3 X4.8921 Y0.8959 I-0.1909 J-0.1218
|
||||
G3 X4.8763 Y0.9135 I-0.1602 J-0.1276
|
||||
G3 X4.8591 Y0.9287 I-0.1379 J-0.1385
|
||||
G3 X4.8402 Y0.9418 I-0.1212 J-0.1544
|
||||
G3 X4.8192 Y0.9531 I-0.1088 J-0.1784
|
||||
G3 X4.7971 Y0.9618 I-0.085 J-0.1835
|
||||
G3 X4.7732 Y0.9681 I-0.0682 J-0.2081
|
||||
G3 X4.7487 Y0.9718 I-0.0472 J-0.2288
|
||||
G3 X4.7219 Y0.9731 I-0.0269 J-0.2747
|
||||
G3 X4.6944 Y0.9718 I0 J-0.2778
|
||||
G3 X4.6698 Y0.968 I0.0226 J-0.2269
|
||||
G3 X4.6458 Y0.9614 I0.0436 J-0.206
|
||||
G3 X4.6239 Y0.9524 I0.0608 J-0.1793
|
||||
G3 X4.6033 Y0.941 I0.0938 J-0.1933
|
||||
G3 X4.5845 Y0.9276 I0.1085 J-0.1725
|
||||
G3 X4.5674 Y0.9123 I0.1271 J-0.159
|
||||
G3 X4.5517 Y0.8947 I0.1514 J-0.1507
|
||||
G3 X4.538 Y0.8755 I0.1766 J-0.1407
|
||||
G3 X4.5256 Y0.8538 I0.2121 J-0.1354
|
||||
G3 X4.5154 Y0.8311 I0.2413 J-0.1223
|
||||
G3 X4.5065 Y0.8055 I0.2984 J-0.1182
|
||||
G3 X4.4997 Y0.7792 I0.3216 J-0.0968
|
||||
G3 X4.4947 Y0.7507 I0.3729 J-0.0801
|
||||
G3 X4.4918 Y0.7219 I0.4066 J-0.0555
|
||||
G3 X4.4908 Y0.6905 I0.4804 J-0.0313
|
||||
G0 Z0.125
|
||||
G0 X5.1552 Y0.6905
|
||||
G1 Z-0.01 F10
|
||||
G2 X5.153 Y0.6348 I-0.7056 J0 F40
|
||||
G2 X5.1469 Y0.5855 I-0.5592 J0.0443
|
||||
G2 X5.1362 Y0.537 I-0.4973 J0.0842
|
||||
G2 X5.1219 Y0.494 I-0.4061 J0.1107
|
||||
G2 X5.1034 Y0.4526 I-0.4475 J0.1756
|
||||
G2 X5.0825 Y0.4161 I-0.3674 J0.1859
|
||||
G2 X5.058 Y0.3821 I-0.3264 J0.2094
|
||||
G2 X5.0309 Y0.3521 I-0.2803 J0.2261
|
||||
G2 X5.0006 Y0.3252 I-0.2579 J0.2609
|
||||
G2 X4.9676 Y0.302 I-0.2269 J0.2867
|
||||
G2 X4.9322 Y0.2824 I-0.1983 J0.3171
|
||||
G2 X4.8933 Y0.266 I-0.1783 J0.3683
|
||||
G2 X4.8529 Y0.2534 I-0.1576 J0.4351
|
||||
G2 X4.8106 Y0.2443 I-0.1231 J0.4701
|
||||
G2 X4.7676 Y0.239 I-0.0841 J0.4988
|
||||
G2 X4.7219 Y0.2371 I-0.0457 J0.5609
|
||||
G2 X4.6774 Y0.239 I0 J0.5346
|
||||
G2 X4.6352 Y0.2443 I0.0407 J0.4884
|
||||
G2 X4.5936 Y0.2534 I0.0806 J0.4691
|
||||
G2 X4.5536 Y0.266 I0.1189 J0.4479
|
||||
G2 X4.5149 Y0.2824 I0.1418 J0.3881
|
||||
G2 X4.4795 Y0.302 I0.1683 J0.3468
|
||||
G2 X4.4463 Y0.3252 I0.2011 J0.3229
|
||||
G2 X4.4154 Y0.3521 I0.2387 J0.3054
|
||||
G2 X4.3877 Y0.3821 I0.2524 J0.2608
|
||||
G2 X4.3627 Y0.4161 I0.2987 J0.246
|
||||
G2 X4.3414 Y0.4526 I0.3422 J0.2241
|
||||
G2 X4.3225 Y0.494 I0.4215 J0.2176
|
||||
G2 X4.3079 Y0.537 I0.3858 J0.1543
|
||||
G2 X4.297 Y0.5855 I0.4777 J0.1328
|
||||
G2 X4.2908 Y0.6348 I0.5427 J0.0937
|
||||
G2 X4.2885 Y0.6905 I0.6897 J0.0557
|
||||
G2 X4.2909 Y0.7462 I0.6678 J0
|
||||
G2 X4.2973 Y0.7956 I0.5306 J-0.0444
|
||||
G2 X4.3086 Y0.844 I0.473 J-0.0846
|
||||
G2 X4.3237 Y0.8871 I0.3899 J-0.1124
|
||||
G2 X4.3432 Y0.9285 I0.4519 J-0.1874
|
||||
G2 X4.365 Y0.9652 I0.376 J-0.199
|
||||
G2 X4.3904 Y0.9993 I0.3361 J-0.2236
|
||||
G2 X4.4185 Y1.0297 I0.2923 J-0.2425
|
||||
G2 X4.4497 Y1.0569 I0.2779 J-0.287
|
||||
G2 X4.4829 Y1.0802 I0.2379 J-0.303
|
||||
G2 X4.5184 Y1.1 I0.2055 J-0.3276
|
||||
G2 X4.5567 Y1.1163 I0.1789 J-0.3656
|
||||
G2 X4.5964 Y1.129 I0.1604 J-0.4356
|
||||
G2 X4.6372 Y1.138 I0.1212 J-0.4502
|
||||
G2 X4.6787 Y1.1434 I0.0819 J-0.4678
|
||||
G2 X4.7219 Y1.1452 I0.0432 J-0.5057
|
||||
G2 X4.7663 Y1.1434 I0 J-0.535
|
||||
G2 X4.8085 Y1.138 I-0.0407 J-0.4886
|
||||
G2 X4.8501 Y1.1289 I-0.0806 J-0.4692
|
||||
G2 X4.8902 Y1.1163 I-0.1189 J-0.4478
|
||||
G2 X4.9288 Y1.0999 I-0.1394 J-0.3816
|
||||
G2 X4.9643 Y1.0802 I-0.1667 J-0.3421
|
||||
G2 X4.9975 Y1.0568 I-0.2001 J-0.3191
|
||||
G2 X5.0284 Y1.0297 I-0.2393 J-0.3033
|
||||
G2 X5.0561 Y0.9993 I-0.2595 J-0.2651
|
||||
G2 X5.0811 Y0.9652 I-0.3049 J-0.2492
|
||||
G2 X5.1024 Y0.9285 I-0.3477 J-0.2267
|
||||
G2 X5.1213 Y0.8871 I-0.4252 J-0.219
|
||||
G2 X5.1358 Y0.844 I-0.3859 J-0.1543
|
||||
G2 X5.1467 Y0.7956 I-0.4781 J-0.1328
|
||||
G2 X5.1529 Y0.7462 I-0.5432 J-0.0937
|
||||
G2 X5.1552 Y0.6905 I-0.6906 J-0.0557
|
||||
G0 Z0.125
|
||||
G0 X5.831 Y0.2547
|
||||
G1 Z-0.01 F10
|
||||
G3 X5.8176 Y0.2759 I-1.044 J-0.6457 F40
|
||||
G3 X5.8023 Y0.2991 I-1.2661 J-0.8193
|
||||
G3 X5.7865 Y0.3221 I-1.3802 J-0.9298
|
||||
G3 X5.7688 Y0.347 I-1.648 J-1.1507
|
||||
G3 X5.7507 Y0.3716 I-1.2024 J-0.8671
|
||||
G3 X5.7315 Y0.3966 I-1.2587 J-0.9478
|
||||
G3 X5.7118 Y0.4213 I-1.2783 J-1.0032
|
||||
G3 X5.691 Y0.4462 I-1.3393 J-1.0938
|
||||
G3 X5.6697 Y0.4708 I-1.3401 J-1.1372
|
||||
G3 X5.6481 Y0.4949 I-1.3041 J-1.1488
|
||||
G3 X5.6261 Y0.5186 I-1.2762 J-1.1671
|
||||
G3 X5.6037 Y0.5417 I-1.2437 J-1.1807
|
||||
G3 X5.5807 Y0.5643 I-0.7609 J-0.7501
|
||||
G3 X5.5585 Y0.5849 I-0.6558 J-0.6866
|
||||
G3 X5.5355 Y0.6048 I-0.5973 J-0.6668
|
||||
G3 X5.5132 Y0.6227 I-0.5113 J-0.6113
|
||||
G1 X5.5132 Y0.2547
|
||||
G1 X5.3173 Y0.2547
|
||||
G1 X5.3173 Y1.1251
|
||||
G1 X5.5132 Y1.1251
|
||||
G1 X5.5132 Y0.796
|
||||
G3 X5.5514 Y0.8364 I-4.1871 J3.9914
|
||||
G3 X5.59 Y0.8782 I-4.4359 J4.1481
|
||||
G3 X5.6283 Y0.9203 I-4.5842 J4.207
|
||||
G3 X5.6671 Y0.9637 I-4.8507 J4.3705
|
||||
G2 X5.7058 Y1.0073 I26.9704 J-23.868
|
||||
G2 X5.7417 Y1.0477 I23.1463 J-20.5506
|
||||
G2 X5.7777 Y1.088 I21.3614 J-19.0327
|
||||
G2 X5.8109 Y1.1251 I18.1034 J-16.1914
|
||||
G1 X6.0433 Y1.1251
|
||||
G2 X5.9984 Y1.0726 I-5.3969 J4.5615
|
||||
G2 X5.9539 Y1.0215 I-5.1497 J4.4395
|
||||
G2 X5.9089 Y0.9709 I-5.0078 J4.405
|
||||
G2 X5.8643 Y0.9217 I-4.7755 J4.2874
|
||||
G2 X5.8191 Y0.8729 I-4.3297 J3.9689
|
||||
G2 X5.7721 Y0.8234 I-4.526 J4.244
|
||||
G2 X5.7246 Y0.7743 I-4.6029 J4.4123
|
||||
G2 X5.6753 Y0.7244 I-4.8095 J4.7102
|
||||
G2 X5.7262 Y0.6798 I-0.8185 J-0.9847
|
||||
G2 X5.7778 Y0.6296 I-0.9824 J-1.0622
|
||||
G2 X5.8269 Y0.577 I-1.1027 J-1.0792
|
||||
G2 X5.8769 Y0.5185 I-1.3152 J-1.1722
|
||||
G2 X5.9244 Y0.458 I-1.6952 J-1.3829
|
||||
G2 X5.9722 Y0.3929 I-1.9177 J-1.4551
|
||||
G2 X6.0177 Y0.3262 I-2.064 J-1.4598
|
||||
G2 X6.0634 Y0.2547 I-2.3302 J-1.5388
|
||||
G1 X5.831 Y0.2547
|
||||
G0 Z0.125
|
||||
G0 X6.3404 Y0.6905
|
||||
G1 Z-0.01 F10
|
||||
G3 X6.3415 Y0.6586 I0.4971 J0 F40
|
||||
G3 X6.3444 Y0.6296 I0.4109 J0.0265
|
||||
G3 X6.3494 Y0.601 I0.3733 J0.0507
|
||||
G3 X6.3561 Y0.575 I0.3139 J0.0676
|
||||
G3 X6.365 Y0.5497 I0.3036 J0.0925
|
||||
G3 X6.3753 Y0.5271 I0.2511 J0.1004
|
||||
G3 X6.3876 Y0.5056 I0.2254 J0.1151
|
||||
G3 X6.4013 Y0.4864 I0.1934 J0.124
|
||||
G3 X6.417 Y0.4689 I0.1636 J0.1303
|
||||
G3 X6.4342 Y0.4536 I0.1398 J0.1398
|
||||
G3 X6.4529 Y0.4405 I0.1224 J0.1548
|
||||
G3 X6.4736 Y0.4293 I0.109 J0.1765
|
||||
G3 X6.4954 Y0.4206 I0.0819 J0.174
|
||||
G3 X6.5194 Y0.4142 I0.0674 J0.205
|
||||
G3 X6.5441 Y0.4105 I0.0471 J0.2296
|
||||
G3 X6.5715 Y0.4092 I0.0275 J0.2849
|
||||
G3 X6.5984 Y0.4105 I0 J0.2758
|
||||
G3 X6.6229 Y0.4142 I-0.0227 J0.2323
|
||||
G3 X6.6468 Y0.4206 I-0.0443 J0.2143
|
||||
G3 X6.6689 Y0.4293 I-0.0629 J0.192
|
||||
G3 X6.6898 Y0.4405 I-0.0881 J0.1899
|
||||
G3 X6.7088 Y0.4536 I-0.1024 J0.1678
|
||||
G3 X6.726 Y0.4689 I-0.1208 J0.154
|
||||
G3 X6.7417 Y0.4864 I-0.1445 J0.1452
|
||||
G3 X6.7555 Y0.5056 I-0.1798 J0.1433
|
||||
G3 X6.7678 Y0.5271 I-0.2133 J0.1367
|
||||
G3 X6.778 Y0.5497 I-0.2412 J0.1232
|
||||
G3 X6.787 Y0.575 I-0.295 J0.1181
|
||||
G3 X6.7937 Y0.601 I-0.3069 J0.0937
|
||||
G3 X6.7987 Y0.6296 I-0.3679 J0.0794
|
||||
G3 X6.8016 Y0.6586 I-0.4076 J0.0554
|
||||
G3 X6.8027 Y0.6905 I-0.4955 J0.032
|
||||
G3 X6.8016 Y0.7225 I-0.4983 J0
|
||||
G3 X6.7987 Y0.7516 I-0.4161 J-0.0268
|
||||
G3 X6.7937 Y0.7804 I-0.3801 J-0.0514
|
||||
G3 X6.787 Y0.8067 I-0.3232 J-0.0691
|
||||
G3 X6.778 Y0.8324 I-0.3076 J-0.0928
|
||||
G3 X6.7678 Y0.8551 I-0.252 J-0.0999
|
||||
G3 X6.7554 Y0.8767 I-0.2249 J-0.1141
|
||||
G3 X6.7417 Y0.8959 I-0.1909 J-0.1218
|
||||
G3 X6.726 Y0.9135 I-0.1602 J-0.1276
|
||||
G3 X6.7088 Y0.9287 I-0.1379 J-0.1385
|
||||
G3 X6.6898 Y0.9418 I-0.1212 J-0.1544
|
||||
G3 X6.6689 Y0.9531 I-0.1088 J-0.1784
|
||||
G3 X6.6468 Y0.9618 I-0.085 J-0.1835
|
||||
G3 X6.6229 Y0.9681 I-0.0682 J-0.2081
|
||||
G3 X6.5984 Y0.9718 I-0.0472 J-0.2288
|
||||
G3 X6.5715 Y0.9731 I-0.0269 J-0.2747
|
||||
G3 X6.5441 Y0.9718 I0 J-0.2778
|
||||
G3 X6.5194 Y0.968 I0.0226 J-0.2269
|
||||
G3 X6.4954 Y0.9614 I0.0436 J-0.206
|
||||
G3 X6.4736 Y0.9524 I0.0608 J-0.1793
|
||||
G3 X6.4529 Y0.941 I0.0938 J-0.1933
|
||||
G3 X6.4342 Y0.9276 I0.1085 J-0.1725
|
||||
G3 X6.417 Y0.9123 I0.1271 J-0.159
|
||||
G3 X6.4013 Y0.8947 I0.1514 J-0.1507
|
||||
G3 X6.3876 Y0.8755 I0.1766 J-0.1407
|
||||
G3 X6.3753 Y0.8538 I0.2121 J-0.1354
|
||||
G3 X6.3651 Y0.8311 I0.2413 J-0.1223
|
||||
G3 X6.3561 Y0.8055 I0.2984 J-0.1182
|
||||
G3 X6.3494 Y0.7792 I0.3216 J-0.0968
|
||||
G3 X6.3444 Y0.7507 I0.3729 J-0.0801
|
||||
G3 X6.3415 Y0.7219 I0.4066 J-0.0555
|
||||
G3 X6.3404 Y0.6905 I0.4804 J-0.0313
|
||||
G0 Z0.125
|
||||
G0 X7.0049 Y0.6905
|
||||
G1 Z-0.01 F10
|
||||
G2 X7.0027 Y0.6348 I-0.7056 J0 F40
|
||||
G2 X6.9965 Y0.5855 I-0.5592 J0.0443
|
||||
G2 X6.9859 Y0.537 I-0.4973 J0.0842
|
||||
G2 X6.9716 Y0.494 I-0.4061 J0.1107
|
||||
G2 X6.953 Y0.4526 I-0.4475 J0.1756
|
||||
G2 X6.9322 Y0.4161 I-0.3674 J0.1859
|
||||
G2 X6.9077 Y0.3821 I-0.3264 J0.2094
|
||||
G2 X6.8805 Y0.3521 I-0.2803 J0.2261
|
||||
G2 X6.8503 Y0.3252 I-0.2579 J0.2609
|
||||
G2 X6.8173 Y0.302 I-0.2269 J0.2867
|
||||
G2 X6.7819 Y0.2824 I-0.1983 J0.3171
|
||||
G2 X6.743 Y0.266 I-0.1783 J0.3683
|
||||
G2 X6.7026 Y0.2534 I-0.1576 J0.4351
|
||||
G2 X6.6602 Y0.2443 I-0.1231 J0.4701
|
||||
G2 X6.6172 Y0.239 I-0.0841 J0.4988
|
||||
G2 X6.5715 Y0.2371 I-0.0457 J0.5609
|
||||
G2 X6.5271 Y0.239 I0 J0.5346
|
||||
G2 X6.4849 Y0.2443 I0.0407 J0.4884
|
||||
G2 X6.4433 Y0.2534 I0.0806 J0.4691
|
||||
G2 X6.4032 Y0.266 I0.1189 J0.4479
|
||||
G2 X6.3646 Y0.2824 I0.1418 J0.3881
|
||||
G2 X6.3291 Y0.302 I0.1683 J0.3468
|
||||
G2 X6.2959 Y0.3252 I0.2011 J0.3229
|
||||
G2 X6.2651 Y0.3521 I0.2387 J0.3054
|
||||
G2 X6.2374 Y0.3821 I0.2524 J0.2608
|
||||
G2 X6.2123 Y0.4161 I0.2987 J0.246
|
||||
G2 X6.191 Y0.4526 I0.3422 J0.2241
|
||||
G2 X6.1721 Y0.494 I0.4215 J0.2176
|
||||
G2 X6.1576 Y0.537 I0.3858 J0.1544
|
||||
G2 X6.1467 Y0.5855 I0.4777 J0.1328
|
||||
G2 X6.1405 Y0.6348 I0.5427 J0.0937
|
||||
G2 X6.1382 Y0.6905 I0.6897 J0.0557
|
||||
G2 X6.1405 Y0.7462 I0.6678 J0
|
||||
G2 X6.147 Y0.7956 I0.5306 J-0.0444
|
||||
G2 X6.1583 Y0.844 I0.473 J-0.0846
|
||||
G2 X6.1734 Y0.8871 I0.3899 J-0.1124
|
||||
G2 X6.1929 Y0.9285 I0.4519 J-0.1874
|
||||
G2 X6.2147 Y0.9652 I0.376 J-0.199
|
||||
G2 X6.2401 Y0.9993 I0.3361 J-0.2236
|
||||
G2 X6.2682 Y1.0297 I0.2923 J-0.2425
|
||||
G2 X6.2994 Y1.0569 I0.2779 J-0.287
|
||||
G2 X6.3326 Y1.0802 I0.2379 J-0.303
|
||||
G2 X6.3681 Y1.1 I0.2055 J-0.3276
|
||||
G2 X6.4064 Y1.1163 I0.1789 J-0.3656
|
||||
G2 X6.4461 Y1.129 I0.1604 J-0.4356
|
||||
G2 X6.4869 Y1.138 I0.1212 J-0.4502
|
||||
G2 X6.5284 Y1.1434 I0.0819 J-0.4678
|
||||
G2 X6.5715 Y1.1452 I0.0432 J-0.5057
|
||||
G2 X6.616 Y1.1434 I0 J-0.535
|
||||
G2 X6.6582 Y1.138 I-0.0407 J-0.4886
|
||||
G2 X6.6998 Y1.1289 I-0.0806 J-0.4692
|
||||
G2 X6.7399 Y1.1163 I-0.1189 J-0.4478
|
||||
G2 X6.7785 Y1.0999 I-0.1394 J-0.3816
|
||||
G2 X6.814 Y1.0802 I-0.1667 J-0.3421
|
||||
G2 X6.8471 Y1.0568 I-0.2001 J-0.3191
|
||||
G2 X6.878 Y1.0297 I-0.2393 J-0.3033
|
||||
G2 X6.9058 Y0.9993 I-0.2595 J-0.2651
|
||||
G2 X6.9308 Y0.9652 I-0.3049 J-0.2492
|
||||
G2 X6.9521 Y0.9285 I-0.3477 J-0.2267
|
||||
G2 X6.971 Y0.8871 I-0.4252 J-0.219
|
||||
G2 X6.9855 Y0.844 I-0.3859 J-0.1543
|
||||
G2 X6.9964 Y0.7956 I-0.4781 J-0.1328
|
||||
G2 X7.0026 Y0.7462 I-0.5432 J-0.0937
|
||||
G2 X7.0049 Y0.6905 I-0.6906 J-0.0557
|
||||
G0 Z0.125
|
||||
G0 X7.9912 Y0.8965
|
||||
G1 Z-0.01 F10
|
||||
G2 X7.99 Y0.8728 I-0.237 J0 F40
|
||||
G2 X7.9865 Y0.8497 I-0.2267 J0.0228
|
||||
G2 X7.9807 Y0.8272 I-0.2234 J0.0459
|
||||
G2 X7.9724 Y0.8048 I-0.2271 J0.0715
|
||||
G2 X7.9623 Y0.7832 I-0.3646 J0.1563
|
||||
G2 X7.9507 Y0.7617 I-0.3716 J0.1865
|
||||
G2 X7.9379 Y0.7409 I-0.371 J0.2144
|
||||
G2 X7.9234 Y0.7201 I-0.3849 J0.2528
|
||||
G2 X7.9079 Y0.7 I-0.5278 J0.3898
|
||||
G2 X7.8914 Y0.68 I-0.5353 J0.4282
|
||||
G2 X7.8741 Y0.6607 I-0.5316 J0.4593
|
||||
G2 X7.8556 Y0.6416 I-0.5427 J0.505
|
||||
G1 X7.7815 Y0.57
|
||||
G3 X7.7721 Y0.5611 I0.8861 J-0.9498
|
||||
G3 X7.7618 Y0.5513 I1.0881 J-1.1433
|
||||
G3 X7.7517 Y0.5413 I1.2053 J-1.2439
|
||||
G3 X7.7406 Y0.5304 I1.4521 J-1.4741
|
||||
G1 X7.6986 Y0.4858
|
||||
G3 X7.6886 Y0.4744 I1.1214 J-0.996
|
||||
G3 X7.6796 Y0.464 I0.9432 J-0.8208
|
||||
G3 X7.6707 Y0.4534 I0.8658 J-0.7369
|
||||
G3 X7.6628 Y0.4437 I0.7169 J-0.5953
|
||||
G3 X7.6552 Y0.4338 I0.1702 J-0.1375
|
||||
G3 X7.65 Y0.426 I0.0998 J-0.0716
|
||||
G3 X7.6456 Y0.4178 I0.0757 J-0.046
|
||||
G3 X7.6433 Y0.4117 I0.0391 J-0.0185
|
||||
G1 X8.0176 Y0.4117
|
||||
G1 X8.0176 Y0.2547
|
||||
G1 X7.4373 Y0.2547
|
||||
G2 X7.4363 Y0.2616 I0.1145 J0.0207
|
||||
G2 X7.4354 Y0.2704 I0.1829 J0.0218
|
||||
G2 X7.435 Y0.2792 I0.2268 J0.0161
|
||||
G2 X7.4348 Y0.2899 I0.3344 J0.0107
|
||||
G1 X7.4348 Y0.2998
|
||||
G1 X7.4348 Y0.3081
|
||||
G1 X7.4348 Y0.3148
|
||||
G1 X7.4348 Y0.32
|
||||
G2 X7.4361 Y0.3501 I0.3578 J0
|
||||
G2 X7.4397 Y0.3778 I0.3087 J-0.026
|
||||
G2 X7.4458 Y0.4051 I0.2878 J-0.0507
|
||||
G2 X7.4543 Y0.4306 I0.2595 J-0.0719
|
||||
G2 X7.4648 Y0.4553 I0.3938 J-0.1527
|
||||
G2 X7.4767 Y0.4791 I0.3744 J-0.1733
|
||||
G2 X7.4902 Y0.502 I0.3612 J-0.1964
|
||||
G2 X7.5052 Y0.5241 I0.3512 J-0.2214
|
||||
G2 X7.5213 Y0.5454 I0.4675 J-0.3386
|
||||
G2 X7.5386 Y0.566 I0.457 J-0.3645
|
||||
G2 X7.5568 Y0.5859 I0.4444 J-0.3892
|
||||
G2 X7.5761 Y0.6051 I0.4388 J-0.4211
|
||||
G1 X7.6546 Y0.6805
|
||||
G3 X7.6697 Y0.6949 I-6.5538 J6.8409
|
||||
G3 X7.6838 Y0.7086 I-5.8415 J6.0705
|
||||
G3 X7.6979 Y0.7223 I-5.5113 J5.7006
|
||||
G3 X7.7111 Y0.7351 I-4.8745 J5.0171
|
||||
G3 X7.7242 Y0.7482 I-0.5266 J0.5392
|
||||
G3 X7.7359 Y0.7606 I-0.4648 J0.4531
|
||||
G3 X7.7474 Y0.7733 I-0.4416 J0.4084
|
||||
G3 X7.7576 Y0.7854 I-0.388 J0.3389
|
||||
G3 X7.7673 Y0.7979 I-0.2179 J0.1789
|
||||
G3 X7.7755 Y0.8099 I-0.1921 J0.1404
|
||||
G3 X7.7829 Y0.8223 I-0.1846 J0.1184
|
||||
G3 X7.789 Y0.8343 I-0.1653 J0.0911
|
||||
G3 X7.794 Y0.8468 I-0.1205 J0.0556
|
||||
G3 X7.7975 Y0.859 I-0.1118 J0.0384
|
||||
G3 X7.7996 Y0.8715 I-0.111 J0.0253
|
||||
G3 X7.8003 Y0.884 I-0.1104 J0.0125
|
||||
G3 X7.798 Y0.9112 I-0.1655 J0
|
||||
G3 X7.7924 Y0.9311 I-0.0937 J-0.0156
|
||||
G3 X7.7824 Y0.9488 I-0.0702 J-0.0283
|
||||
G3 X7.7689 Y0.9618 I-0.0509 J-0.0389
|
||||
G3 X7.7525 Y0.9716 I-0.064 J-0.0889
|
||||
G3 X7.7337 Y0.9788 I-0.0523 J-0.1085
|
||||
G3 X7.714 Y0.9829 I-0.0372 J-0.1282
|
||||
G3 X7.691 Y0.9844 I-0.023 J-0.1742
|
||||
G3 X7.6741 Y0.9838 I0 J-0.2082
|
||||
G3 X7.6582 Y0.9818 I0.0152 J-0.1867
|
||||
G3 X7.6426 Y0.9784 I0.0299 J-0.1776
|
||||
G3 X7.6276 Y0.9738 I0.0434 J-0.166
|
||||
G3 X7.613 Y0.9681 I0.124 J-0.3427
|
||||
G3 X7.5994 Y0.9621 I0.1248 J-0.3035
|
||||
G3 X7.586 Y0.9556 I0.1317 J-0.2831
|
||||
G3 X7.5736 Y0.9486 I0.1322 J-0.2521
|
||||
G3 X7.5615 Y0.9412 I0.2233 J-0.3784
|
||||
G3 X7.5508 Y0.9342 I0.1896 J-0.2988
|
||||
G3 X7.5405 Y0.9268 I0.179 J-0.2609
|
||||
G3 X7.5315 Y0.9198 I0.1505 J-0.2014
|
||||
G3 X7.5228 Y0.9125 I0.4664 J-0.5685
|
||||
G3 X7.5161 Y0.9067 I0.2834 J-0.3348
|
||||
G3 X7.5096 Y0.9008 I0.2157 J-0.2447
|
||||
G3 X7.5052 Y0.8965 I0.1113 J-0.1196
|
||||
G1 X7.4122 Y1.0271
|
||||
G2 X7.4408 Y1.0516 I0.3033 J-0.3254
|
||||
G2 X7.472 Y1.0741 I0.2859 J-0.3642
|
||||
G2 X7.505 Y1.0939 I0.2634 J-0.4
|
||||
G2 X7.541 Y1.1119 I0.2525 J-0.4598
|
||||
G2 X7.5784 Y1.1265 I0.1528 J-0.3372
|
||||
G2 X7.6171 Y1.1369 I0.115 J-0.3507
|
||||
G2 X7.6567 Y1.1431 I0.078 J-0.3692
|
||||
G2 X7.6986 Y1.1452 I0.0419 J-0.4097
|
||||
G2 X7.7368 Y1.1441 I0 J-0.6209
|
||||
G2 X7.7698 Y1.1408 I-0.0288 J-0.4669
|
||||
G2 X7.8025 Y1.1351 I-0.0537 J-0.4022
|
||||
G2 X7.8304 Y1.1276 I-0.0656 J-0.3011
|
||||
G2 X7.8576 Y1.1176 I-0.0975 J-0.3061
|
||||
G2 X7.8808 Y1.1064 I-0.0996 J-0.2366
|
||||
G2 X7.9028 Y1.0929 I-0.1113 J-0.2042
|
||||
G2 X7.9215 Y1.078 I-0.1143 J-0.1635
|
||||
G2 X7.9383 Y1.0611 I-0.1312 J-0.1467
|
||||
G2 X7.9526 Y1.0425 I-0.1419 J-0.1243
|
||||
G2 X7.9645 Y1.0224 I-0.1576 J-0.1068
|
||||
G2 X7.9743 Y1.0002 I-0.1832 J-0.0937
|
||||
G2 X7.9816 Y0.9769 I-0.2296 J-0.085
|
||||
G2 X7.987 Y0.9513 I-0.2735 J-0.0712
|
||||
G2 X7.9901 Y0.9253 I-0.3042 J-0.0498
|
||||
G2 X7.9912 Y0.8965 I-0.3724 J-0.0288
|
||||
G0 Z0.125
|
||||
(remove M5 and M30)
|
File diff suppressed because it is too large
Load Diff
@ -1,437 +0,0 @@
|
||||
% ----------------------------------------------------------------------------------------
|
||||
% 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.
|
||||
% ----------------------------------------------------------------------------------------
|
||||
|
||||
% This MATLAB script was written for the purpose of being a GRBL planner simulator. This
|
||||
% simulator is a rough representation of the actual workings of Grbl on the Arduino, but
|
||||
% was used to hone and proof the actual planner by providing quick visual feedback on its
|
||||
% functionality when experimented on. This script should be considered for educational
|
||||
% purposes only. This script requires and executes a pre-parsed g-code file from the
|
||||
% matlab_convert.py script that is in a specific non-g-code format.
|
||||
|
||||
% There will be two figures plotted. The first is the line motion paths of the complete
|
||||
% g-code program. The second is a representation of Grbl's planner buffer as new line
|
||||
% motions are fed to it, plotting the velocity profiles the stepper motors will execute.
|
||||
% Every time the user inputs an <Enter>, 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('<NOTE: Press Enter to Advance One G-Code Line Motion>');
|
||||
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
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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()
|
File diff suppressed because it is too large
Load Diff
@ -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)
|
25
test/test.py
25
test/test.py
@ -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())
|
Loading…
Reference in New Issue
Block a user