\******************************************************************************/
-#include "machine.h"
+#include "axes.h"
+
+#include "plan/planner.h"
+
+#include <math.h>
+
+
+axis_config_t axes[AXES] = {
+ {
+ .axis_mode = X_AXIS_MODE,
+ .velocity_max = X_VELOCITY_MAX,
+ .feedrate_max = X_FEEDRATE_MAX,
+ .travel_min = X_TRAVEL_MIN,
+ .travel_max = X_TRAVEL_MAX,
+ .jerk_max = X_JERK_MAX,
+ .jerk_homing = X_JERK_HOMING,
+ .junction_dev = X_JUNCTION_DEVIATION,
+ .search_velocity = X_SEARCH_VELOCITY,
+ .latch_velocity = X_LATCH_VELOCITY,
+ .latch_backoff = X_LATCH_BACKOFF,
+ .zero_backoff = X_ZERO_BACKOFF,
+ }, {
+ .axis_mode = Y_AXIS_MODE,
+ .velocity_max = Y_VELOCITY_MAX,
+ .feedrate_max = Y_FEEDRATE_MAX,
+ .travel_min = Y_TRAVEL_MIN,
+ .travel_max = Y_TRAVEL_MAX,
+ .jerk_max = Y_JERK_MAX,
+ .jerk_homing = Y_JERK_HOMING,
+ .junction_dev = Y_JUNCTION_DEVIATION,
+ .search_velocity = Y_SEARCH_VELOCITY,
+ .latch_velocity = Y_LATCH_VELOCITY,
+ .latch_backoff = Y_LATCH_BACKOFF,
+ .zero_backoff = Y_ZERO_BACKOFF,
+ }, {
+ .axis_mode = Z_AXIS_MODE,
+ .velocity_max = Z_VELOCITY_MAX,
+ .feedrate_max = Z_FEEDRATE_MAX,
+ .travel_min = Z_TRAVEL_MIN,
+ .travel_max = Z_TRAVEL_MAX,
+ .jerk_max = Z_JERK_MAX,
+ .jerk_homing = Z_JERK_HOMING,
+ .junction_dev = Z_JUNCTION_DEVIATION,
+ .search_velocity = Z_SEARCH_VELOCITY,
+ .latch_velocity = Z_LATCH_VELOCITY,
+ .latch_backoff = Z_LATCH_BACKOFF,
+ .zero_backoff = Z_ZERO_BACKOFF,
+ }, {
+ .axis_mode = A_AXIS_MODE,
+ .velocity_max = A_VELOCITY_MAX,
+ .feedrate_max = A_FEEDRATE_MAX,
+ .travel_min = A_TRAVEL_MIN,
+ .travel_max = A_TRAVEL_MAX,
+ .jerk_max = A_JERK_MAX,
+ .jerk_homing = A_JERK_HOMING,
+ .junction_dev = A_JUNCTION_DEVIATION,
+ .radius = A_RADIUS,
+ .search_velocity = A_SEARCH_VELOCITY,
+ .latch_velocity = A_LATCH_VELOCITY,
+ .latch_backoff = A_LATCH_BACKOFF,
+ .zero_backoff = A_ZERO_BACKOFF,
+ }, {
+ .axis_mode = B_AXIS_MODE,
+ .velocity_max = B_VELOCITY_MAX,
+ .feedrate_max = B_FEEDRATE_MAX,
+ .travel_min = B_TRAVEL_MIN,
+ .travel_max = B_TRAVEL_MAX,
+ .jerk_max = B_JERK_MAX,
+ .junction_dev = B_JUNCTION_DEVIATION,
+ .radius = B_RADIUS,
+ }, {
+ .axis_mode = C_AXIS_MODE,
+ .velocity_max = C_VELOCITY_MAX,
+ .feedrate_max = C_FEEDRATE_MAX,
+ .travel_min = C_TRAVEL_MIN,
+ .travel_max = C_TRAVEL_MAX,
+ .jerk_max = C_JERK_MAX,
+ .junction_dev = C_JUNCTION_DEVIATION,
+ .radius = C_RADIUS,
+ }
+};
+
+
+/* Jerk functions
+ *
+ * Jerk values can be rather large, often in the billions. This makes
+ * for some pretty big numbers for people to deal with. Jerk values
+ * are stored in the system in truncated format; values are divided by
+ * 1,000,000 then reconstituted before use.
+ *
+ * The axis_jerk() functions expect the jerk in divided-by 1,000,000 form
+ */
+
+/// returns jerk for an axis
+float axes_get_jerk(uint8_t axis) {
+ return axes[axis].jerk_max;
+}
+
+
+/// sets the jerk for an axis, including recirpcal and cached values
+void axes_set_jerk(uint8_t axis, float jerk) {
+ axes[axis].jerk_max = jerk;
+ axes[axis].recip_jerk = 1 / (jerk * JERK_MULTIPLIER);
+}
uint8_t get_axis_mode(int axis) {
- return mach.a[axis].axis_mode;
+ return axes[axis].axis_mode;
}
void set_axis_mode(int axis, uint8_t value) {
if (value < AXIS_MODE_MAX)
- mach.a[axis].axis_mode = value;
+ axes[axis].axis_mode = value;
}
float get_max_velocity(int axis) {
- return mach.a[axis].velocity_max;
+ return axes[axis].velocity_max;
}
void set_max_velocity(int axis, float value) {
- mach.a[axis].velocity_max = value;
+ axes[axis].velocity_max = value;
}
float get_max_feedrate(int axis) {
- return mach.a[axis].feedrate_max;
+ return axes[axis].feedrate_max;
}
void set_max_feedrate(int axis, float value) {
- mach.a[axis].feedrate_max = value;
+ axes[axis].feedrate_max = value;
}
float get_max_jerk(int axis) {
- return mach.a[axis].jerk_max;
+ return axes[axis].jerk_max;
}
void set_max_jerk(int axis, float value) {
- mach.a[axis].jerk_max = value;
+ axes[axis].jerk_max = value;
}
float get_junction_dev(int axis) {
- return mach.a[axis].junction_dev;
+ return axes[axis].junction_dev;
}
void set_junction_dev(int axis, float value) {
- mach.a[axis].junction_dev = value;
+ axes[axis].junction_dev = value;
}
float get_travel_min(int axis) {
- return mach.a[axis].travel_min;
+ return axes[axis].travel_min;
}
void set_travel_min(int axis, float value) {
- mach.a[axis].travel_min = value;
+ axes[axis].travel_min = value;
}
float get_travel_max(int axis) {
- return mach.a[axis].travel_max;
+ return axes[axis].travel_max;
}
void set_travel_max(int axis, float value) {
- mach.a[axis].travel_max = value;
+ axes[axis].travel_max = value;
}
float get_jerk_homing(int axis) {
- return mach.a[axis].jerk_homing;
+ return axes[axis].jerk_homing;
}
void set_jerk_homing(int axis, float value) {
- mach.a[axis].jerk_homing = value;
+ axes[axis].jerk_homing = value;
}
float get_search_vel(int axis) {
- return mach.a[axis].search_velocity;
+ return axes[axis].search_velocity;
}
void set_search_vel(int axis, float value) {
- mach.a[axis].search_velocity = value;
+ axes[axis].search_velocity = value;
}
float get_latch_vel(int axis) {
- return mach.a[axis].latch_velocity;
+ return axes[axis].latch_velocity;
}
void set_latch_vel(int axis, float value) {
- mach.a[axis].latch_velocity = value;
+ axes[axis].latch_velocity = value;
}
float get_latch_backoff(int axis) {
- return mach.a[axis].latch_backoff;
+ return axes[axis].latch_backoff;
}
void set_latch_backoff(int axis, float value) {
- mach.a[axis].latch_backoff = value;
+ axes[axis].latch_backoff = value;
}
float get_zero_backoff(int axis) {
- return mach.a[axis].zero_backoff;
+ return axes[axis].zero_backoff;
}
void set_zero_backoff(int axis, float value) {
- mach.a[axis].zero_backoff = value;
+ axes[axis].zero_backoff = value;
}
--- /dev/null
+/******************************************************************************\
+
+ This file is part of the Buildbotics firmware.
+
+ Copyright (c) 2015 - 2016 Buildbotics LLC
+ Copyright (c) 2010 - 2015 Alden S. Hart, Jr.
+ All rights reserved.
+
+ This file ("the software") is free software: you can redistribute it
+ and/or modify it under the terms of the GNU General Public License,
+ version 2 as published by the Free Software Foundation. You should
+ have received a copy of the GNU General Public License, version 2
+ along with the software. If not, see <http://www.gnu.org/licenses/>.
+
+ The software 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the software. If not, see
+ <http://www.gnu.org/licenses/>.
+
+ For information regarding this software email:
+ "Joseph Coffland" <joseph@buildbotics.com>
+
+\******************************************************************************/
+
+#pragma once
+
+#include "config.h"
+
+
+typedef enum {
+ AXIS_DISABLED, // disable axis
+ AXIS_STANDARD, // axis in coordinated motion w/standard behaviors
+ AXIS_INHIBITED, // axis is computed but not activated
+ AXIS_RADIUS, // rotary axis calibrated to circumference
+ AXIS_MODE_MAX,
+} axis_mode_t;
+
+
+typedef struct {
+ axis_mode_t axis_mode;
+ float feedrate_max; // max velocity in mm/min or deg/min
+ float velocity_max; // max velocity in mm/min or deg/min
+ float travel_max; // max work envelope for soft limits
+ float travel_min; // min work envelope for soft limits
+ float jerk_max; // max jerk (Jm) in mm/min^3 divided by 1 million
+ float jerk_homing; // homing jerk (Jh) in mm/min^3 divided by 1 million
+ float recip_jerk; // reciprocal of current jerk value - with million
+ float junction_dev; // aka cornering delta
+ float radius; // radius in mm for rotary axis modes
+ float search_velocity; // homing search velocity
+ float latch_velocity; // homing latch velocity
+ float latch_backoff; // backoff from switches prior to homing latch movement
+ float zero_backoff; // backoff from switches for machine zero
+} axis_config_t;
+
+
+extern axis_config_t axes[AXES];
+
+float axes_get_jerk(uint8_t axis);
+void axes_set_jerk(uint8_t axis, float jerk);
#include "machine.h"
+typedef enum { // Used for detecting gcode errors. See NIST section 3.4
+ MODAL_GROUP_G0, // {G10,G28,G28.1,G92} non-modal axis commands
+ MODAL_GROUP_G1, // {G0,G1,G2,G3,G80} motion
+ MODAL_GROUP_G2, // {G17,G18,G19} plane selection
+ MODAL_GROUP_G3, // {G90,G91} distance mode
+ MODAL_GROUP_G5, // {G93,G94} feed rate mode
+ MODAL_GROUP_G6, // {G20,G21} units
+ MODAL_GROUP_G7, // {G40,G41,G42} cutter radius compensation
+ MODAL_GROUP_G8, // {G43,G49} tool length offset
+ MODAL_GROUP_G9, // {G98,G99} return mode in canned cycles
+ MODAL_GROUP_G12, // {G54,G55,G56,G57,G58,G59} coordinate system selection
+ MODAL_GROUP_G13, // {G61,G61.1,G64} path control mode
+ MODAL_GROUP_M4, // {M0,M1,M2,M30,M60} stopping
+ MODAL_GROUP_M6, // {M6} tool change
+ MODAL_GROUP_M7, // {M3,M4,M5} spindle turning
+ MODAL_GROUP_M8, // {M7,M8,M9} coolant
+ MODAL_GROUP_M9, // {M48,M49} speed/feed override switches
+} modal_group_t;
+
+#define MODAL_GROUP_COUNT (MODAL_GROUP_M9 + 1)
+
+
typedef struct {
gcode_state_t gn; // gcode input values
gcode_state_t gf; // gcode input flags
--- /dev/null
+/******************************************************************************\
+
+ This file is part of the Buildbotics firmware.
+
+ Copyright (c) 2015 - 2016 Buildbotics LLC
+ Copyright (c) 2010 - 2015 Alden S. Hart, Jr.
+ All rights reserved.
+
+ This file ("the software") is free software: you can redistribute it
+ and/or modify it under the terms of the GNU General Public License,
+ version 2 as published by the Free Software Foundation. You should
+ have received a copy of the GNU General Public License, version 2
+ along with the software. If not, see <http://www.gnu.org/licenses/>.
+
+ The software 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the software. If not, see
+ <http://www.gnu.org/licenses/>.
+
+ For information regarding this software email:
+ "Joseph Coffland" <joseph@buildbotics.com>
+
+\******************************************************************************/
+
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+
+
+/* The difference between next_action_t and motion_mode_t is that
+ * next_action_t is used by the current block, and may carry non-modal
+ * commands, whereas motion_mode_t persists across blocks as G modal group 1
+ */
+
+/// these are in order to optimized CASE statement
+typedef enum {
+ NEXT_ACTION_DEFAULT, // Must be zero (invokes motion modes)
+ NEXT_ACTION_SEARCH_HOME, // G28.2 homing cycle
+ NEXT_ACTION_SET_ABSOLUTE_ORIGIN, // G28.3 origin set
+ NEXT_ACTION_HOMING_NO_SET, // G28.4 homing cycle no coord setting
+ NEXT_ACTION_SET_G28_POSITION, // G28.1 set position in abs coordinates
+ NEXT_ACTION_GOTO_G28_POSITION, // G28 go to machine position
+ NEXT_ACTION_SET_G30_POSITION, // G30.1
+ NEXT_ACTION_GOTO_G30_POSITION, // G30
+ NEXT_ACTION_SET_COORD_DATA, // G10
+ NEXT_ACTION_SET_ORIGIN_OFFSETS, // G92
+ NEXT_ACTION_RESET_ORIGIN_OFFSETS, // G92.1
+ NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS, // G92.2
+ NEXT_ACTION_RESUME_ORIGIN_OFFSETS, // G92.3
+ NEXT_ACTION_DWELL, // G4
+ NEXT_ACTION_STRAIGHT_PROBE, // G38.2
+} next_action_t;
+
+
+typedef enum { // G Modal Group 1
+ MOTION_MODE_RAPID, // G0 - rapid
+ MOTION_MODE_FEED, // G1 - straight feed
+ MOTION_MODE_CW_ARC, // G2 - clockwise arc feed
+ MOTION_MODE_CCW_ARC, // G3 - counter-clockwise arc feed
+ MOTION_MODE_CANCEL_MOTION_MODE, // G80
+ MOTION_MODE_STRAIGHT_PROBE, // G38.2
+ MOTION_MODE_CANNED_CYCLE_81, // G81 - drilling
+ MOTION_MODE_CANNED_CYCLE_82, // G82 - drilling with dwell
+ MOTION_MODE_CANNED_CYCLE_83, // G83 - peck drilling
+ MOTION_MODE_CANNED_CYCLE_84, // G84 - right hand tapping
+ MOTION_MODE_CANNED_CYCLE_85, // G85 - boring, no dwell, feed out
+ MOTION_MODE_CANNED_CYCLE_86, // G86 - boring, spindle stop, rapid out
+ MOTION_MODE_CANNED_CYCLE_87, // G87 - back boring
+ MOTION_MODE_CANNED_CYCLE_88, // G88 - boring, spindle stop, manual out
+ MOTION_MODE_CANNED_CYCLE_89, // G89 - boring, dwell, feed out
+} motion_mode_t;
+
+
+typedef enum { // plane - translates to:
+ // axis_0 axis_1 axis_2
+ PLANE_XY, // G17 X Y Z
+ PLANE_XZ, // G18 X Z Y
+ PLANE_YZ, // G19 Y Z X
+} plane_t;
+
+
+typedef enum {
+ INCHES, // G20
+ MILLIMETERS, // G21
+ DEGREES, // ABC axes (this value used for displays only)
+} units_t;
+
+
+typedef enum {
+ ABSOLUTE_COORDS, // machine coordinate system
+ G54, G55, G56, G57, G58, G59,
+} coord_system_t;
+
+
+/// G Modal Group 13
+typedef enum {
+ PATH_EXACT_PATH, // G61 hits corners but stops only if needed
+ PATH_EXACT_STOP, // G61.1 stops at all corners
+ PATH_CONTINUOUS, // G64 and typically the default mode
+} path_mode_t;
+
+
+typedef enum {
+ ABSOLUTE_MODE, // G90
+ INCREMENTAL_MODE, // G91
+} distance_mode_t;
+
+
+typedef enum {
+ INVERSE_TIME_MODE, // G93
+ UNITS_PER_MINUTE_MODE, // G94
+ UNITS_PER_REVOLUTION_MODE, // G95 (unimplemented)
+} feed_mode_t;
+
+
+typedef enum {
+ ORIGIN_OFFSET_SET, // G92 - set origin offsets
+ ORIGIN_OFFSET_CANCEL, // G92.1 - zero out origin offsets
+ ORIGIN_OFFSET_SUSPEND, // G92.2 - do not apply offsets, but preserve values
+ ORIGIN_OFFSET_RESUME, // G92.3 - resume application of the suspended offsets
+} origin_offset_t;
+
+
+typedef enum {
+ PROGRAM_STOP,
+ PROGRAM_OPTIONAL_STOP,
+ PROGRAM_PALLET_CHANGE_STOP,
+ PROGRAM_END,
+} program_flow_t;
+
+
+/// spindle state settings
+typedef enum {
+ SPINDLE_OFF,
+ SPINDLE_CW,
+ SPINDLE_CCW,
+} spindle_mode_t;
+
+
+/// mist and flood coolant states
+typedef enum {
+ COOLANT_OFF, // all coolant off
+ COOLANT_ON, // request coolant on or indicate both coolants are on
+ COOLANT_MIST, // indicates mist coolant on
+ COOLANT_FLOOD, // indicates flood coolant on
+} coolant_state_t;
+
+
+/// used for spindle and arc dir
+typedef enum {
+ DIRECTION_CW,
+ DIRECTION_CCW,
+} direction_t;
+
+
+/* Gcode model
+ *
+ * - gm is the core Gcode model state. It keeps the internal gcode
+ * state model in normalized, canonical form. All values are unit
+ * converted (to mm) and in the machine coordinate system
+ * (absolute coordinate system). Gm is owned by the machine layer and
+ * should be accessed only through mach_ routines.
+ *
+ * - gn is used by the gcode parser and is re-initialized for
+ * each gcode block. It accepts data in the new gcode block in the
+ * formats present in the block (pre-normalized forms). During
+ * initialization some state elements are necessarily restored
+ * from gm.
+ *
+ * - gf is used by the gcode parser to hold flags for any data that has
+ * changed in gn during the parse. parser.gf.target[]
+ * values are also used by the machine during set_target().
+ */
+
+
+/// Gcode model state
+typedef struct {
+ uint32_t line; // Gcode block line number
+
+ uint8_t tool; // Tool after T and M6
+ uint8_t tool_select; // T - sets this value
+
+ float feed_rate; // F - in mm/min or inverse time mode
+ feed_mode_t feed_mode;
+ float feed_override_factor; // 1.0000 x F feed rate
+ bool feed_override_enable; // M48, M49
+
+ float spindle_speed; // in RPM
+ spindle_mode_t spindle_mode;
+ float spindle_override_factor; // 1.0000 x S spindle speed
+ bool spindle_override_enable; // true = override enabled
+
+ motion_mode_t motion_mode; // Group 1 modal motion
+ plane_t plane; // G17, G18, G19
+ units_t units; // G20, G21
+ coord_system_t coord_system; // G54-G59 - select coordinate system 1-9
+ bool absolute_mode; // G53 true = move in machine coordinates
+ path_mode_t path_mode; // G61
+ distance_mode_t distance_mode; // G91
+ distance_mode_t arc_distance_mode; // G91.1
+
+ bool mist_coolant; // true = mist on (M7), false = off (M9)
+ bool flood_coolant; // true = mist on (M8), false = off (M9)
+
+ next_action_t next_action; // handles G group 1 moves & non-modals
+ program_flow_t program_flow; // used only by the gcode_parser
+
+ // TODO unimplemented gcode parameters
+ // float cutter_radius; // D - cutter radius compensation (0 is off)
+ // float cutter_length; // H - cutter length compensation (0 is off)
+
+ // Used for input only
+ float target[AXES]; // XYZABC where the move should go
+ bool override_enables; // feed and spindle enable
+ bool tool_change; // M6 tool change flag
+
+ float parameter; // P - dwell time in sec, G10 coord select
+ float arc_radius; // R - radius value in arc radius mode
+ float arc_offset[3]; // IJK - used by arc commands
+} gcode_state_t;
\******************************************************************************/
#include "homing.h"
+
+#include "axes.h"
#include "machine.h"
#include "switch.h"
#include "gcode_parser.h"
/// End homing cycle in progress
static void _homing_abort(int8_t axis) {
- mach_set_axis_jerk(axis, hm.saved_jerk); // restore the max jerk value
+ axes_set_jerk(axis, hm.saved_jerk); // restore the max jerk value
// homing state remains HOMING_NOT_HOMED
_homing_error_exit(STAT_HOMING_CYCLE_FAILED);
} else // do not set axis if in G28.4 cycle
mach_set_axis_position(axis, mp_runtime_get_work_position(axis));
- mach_set_axis_jerk(axis, hm.saved_jerk); // restore the max jerk value
+ axes_set_jerk(axis, hm.saved_jerk); // restore the max jerk value
hm.func = _homing_axis_start;
}
/// Fast search for switch, closes switch
static void _homing_axis_search(int8_t axis) {
// use the homing jerk for search onward
- mach_set_axis_jerk(axis, mach.a[axis].jerk_homing);
+ axes_set_jerk(axis, axes[axis].jerk_homing);
_homing_axis_move(axis, hm.search_travel, hm.search_velocity);
hm.func = _homing_axis_latch;
}
hm.homed[axis] = false;
// trap axis mis-configurations
- if (fp_ZERO(mach.a[axis].search_velocity))
+ if (fp_ZERO(axes[axis].search_velocity))
return _homing_error_exit(STAT_HOMING_ERROR_ZERO_SEARCH_VELOCITY);
- if (fp_ZERO(mach.a[axis].latch_velocity))
+ if (fp_ZERO(axes[axis].latch_velocity))
return _homing_error_exit(STAT_HOMING_ERROR_ZERO_LATCH_VELOCITY);
- if (mach.a[axis].latch_backoff < 0)
+ if (axes[axis].latch_backoff < 0)
return _homing_error_exit(STAT_HOMING_ERROR_NEGATIVE_LATCH_BACKOFF);
// calculate and test travel distance
float travel_distance =
- fabs(mach.a[axis].travel_max - mach.a[axis].travel_min) +
- mach.a[axis].latch_backoff;
+ fabs(axes[axis].travel_max - axes[axis].travel_min) +
+ axes[axis].latch_backoff;
if (fp_ZERO(travel_distance))
return _homing_error_exit(STAT_HOMING_ERROR_TRAVEL_MIN_MAX_IDENTICAL);
hm.axis = axis; // persist the axis
// search velocity is always positive
- hm.search_velocity = fabs(mach.a[axis].search_velocity);
+ hm.search_velocity = fabs(axes[axis].search_velocity);
// latch velocity is always positive
- hm.latch_velocity = fabs(mach.a[axis].latch_velocity);
+ hm.latch_velocity = fabs(axes[axis].latch_velocity);
// determine which switch to use
bool min_enabled = switch_is_enabled(MIN_SWITCH(axis));
hm.homing_switch = MIN_SWITCH(axis); // min is the homing switch
hm.limit_switch = MAX_SWITCH(axis); // max would be limit switch
hm.search_travel = -travel_distance; // in negative direction
- hm.latch_backoff = mach.a[axis].latch_backoff; // in positive direction
- hm.zero_backoff = mach.a[axis].zero_backoff;
+ hm.latch_backoff = axes[axis].latch_backoff; // in positive direction
+ hm.zero_backoff = axes[axis].zero_backoff;
} else if (max_enabled) {
// setup parameters for positive travel (homing to the maximum switch)
hm.homing_switch = MAX_SWITCH(axis); // max is homing switch
hm.limit_switch = MIN_SWITCH(axis); // min would be limit switch
hm.search_travel = travel_distance; // in positive direction
- hm.latch_backoff = -mach.a[axis].latch_backoff; // in negative direction
- hm.zero_backoff = -mach.a[axis].zero_backoff;
+ hm.latch_backoff = -axes[axis].latch_backoff; // in negative direction
+ hm.zero_backoff = -axes[axis].zero_backoff;
} else {
// if homing is disabled for the axis then skip to the next axis
return;
}
- hm.saved_jerk = mach_get_axis_jerk(axis); // save the max jerk value
+ hm.saved_jerk = axes_get_jerk(axis); // save the max jerk value
hm.func = _homing_axis_clear; // start the clear
}
#include "machine.h"
#include "config.h"
+#include "axes.h"
#include "gcode_parser.h"
#include "spindle.h"
#include "coolant.h"
{0, 0, 0, 0, 0, 0}, // G59
},
- // Axes
- .a = {
- {
- .axis_mode = X_AXIS_MODE,
- .velocity_max = X_VELOCITY_MAX,
- .feedrate_max = X_FEEDRATE_MAX,
- .travel_min = X_TRAVEL_MIN,
- .travel_max = X_TRAVEL_MAX,
- .jerk_max = X_JERK_MAX,
- .jerk_homing = X_JERK_HOMING,
- .junction_dev = X_JUNCTION_DEVIATION,
- .search_velocity = X_SEARCH_VELOCITY,
- .latch_velocity = X_LATCH_VELOCITY,
- .latch_backoff = X_LATCH_BACKOFF,
- .zero_backoff = X_ZERO_BACKOFF,
- }, {
- .axis_mode = Y_AXIS_MODE,
- .velocity_max = Y_VELOCITY_MAX,
- .feedrate_max = Y_FEEDRATE_MAX,
- .travel_min = Y_TRAVEL_MIN,
- .travel_max = Y_TRAVEL_MAX,
- .jerk_max = Y_JERK_MAX,
- .jerk_homing = Y_JERK_HOMING,
- .junction_dev = Y_JUNCTION_DEVIATION,
- .search_velocity = Y_SEARCH_VELOCITY,
- .latch_velocity = Y_LATCH_VELOCITY,
- .latch_backoff = Y_LATCH_BACKOFF,
- .zero_backoff = Y_ZERO_BACKOFF,
- }, {
- .axis_mode = Z_AXIS_MODE,
- .velocity_max = Z_VELOCITY_MAX,
- .feedrate_max = Z_FEEDRATE_MAX,
- .travel_min = Z_TRAVEL_MIN,
- .travel_max = Z_TRAVEL_MAX,
- .jerk_max = Z_JERK_MAX,
- .jerk_homing = Z_JERK_HOMING,
- .junction_dev = Z_JUNCTION_DEVIATION,
- .search_velocity = Z_SEARCH_VELOCITY,
- .latch_velocity = Z_LATCH_VELOCITY,
- .latch_backoff = Z_LATCH_BACKOFF,
- .zero_backoff = Z_ZERO_BACKOFF,
- }, {
- .axis_mode = A_AXIS_MODE,
- .velocity_max = A_VELOCITY_MAX,
- .feedrate_max = A_FEEDRATE_MAX,
- .travel_min = A_TRAVEL_MIN,
- .travel_max = A_TRAVEL_MAX,
- .jerk_max = A_JERK_MAX,
- .jerk_homing = A_JERK_HOMING,
- .junction_dev = A_JUNCTION_DEVIATION,
- .radius = A_RADIUS,
- .search_velocity = A_SEARCH_VELOCITY,
- .latch_velocity = A_LATCH_VELOCITY,
- .latch_backoff = A_LATCH_BACKOFF,
- .zero_backoff = A_ZERO_BACKOFF,
- }, {
- .axis_mode = B_AXIS_MODE,
- .velocity_max = B_VELOCITY_MAX,
- .feedrate_max = B_FEEDRATE_MAX,
- .travel_min = B_TRAVEL_MIN,
- .travel_max = B_TRAVEL_MAX,
- .jerk_max = B_JERK_MAX,
- .junction_dev = B_JUNCTION_DEVIATION,
- .radius = B_RADIUS,
- }, {
- .axis_mode = C_AXIS_MODE,
- .velocity_max = C_VELOCITY_MAX,
- .feedrate_max = C_FEEDRATE_MAX,
- .travel_min = C_TRAVEL_MIN,
- .travel_max = C_TRAVEL_MAX,
- .jerk_max = C_JERK_MAX,
- .junction_dev = C_JUNCTION_DEVIATION,
- .radius = C_RADIUS,
- }
- },
-
// State
.gm = {.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE},
};
void mach_set_model_line(uint32_t line) {mach.gm.line = line;}
-/* Jerk functions
- *
- * Jerk values can be rather large, often in the billions. This makes
- * for some pretty big numbers for people to deal with. Jerk values
- * are stored in the system in truncated format; values are divided by
- * 1,000,000 then reconstituted before use.
- *
- * The axis_jerk() functions expect the jerk in divided-by 1,000,000 form
- */
-
-/// returns jerk for an axis
-float mach_get_axis_jerk(uint8_t axis) {
- return mach.a[axis].jerk_max;
-}
-
-
-/// sets the jerk for an axis, including recirpcal and cached values
-void mach_set_axis_jerk(uint8_t axis, float jerk) {
- mach.a[axis].jerk_max = jerk;
- mach.a[axis].recip_jerk = 1 / (jerk * JERK_MULTIPLIER);
-}
-
-
/* Coordinate systems and offsets
*
* Functions to get, set and report coordinate systems and work offsets
// Compute time required for rate-limiting axis
for (int axis = 0; axis < AXES; axis++) {
float time = fabs(axis_length[axis]) /
- (mach.gm.motion_mode == MOTION_MODE_RAPID ? mach.a[axis].velocity_max :
- mach.a[axis].feedrate_max);
+ (mach.gm.motion_mode == MOTION_MODE_RAPID ? axes[axis].velocity_max :
+ axes[axis].feedrate_max);
if (max_time < time) max_time = time;
}
// get a fresh stack push
// ALDEN: This shows up in avr-gcc 4.7.0 and avr-libc 1.8.0
static float _calc_ABC(uint8_t axis, float target[], float flag[]) {
- if (mach.a[axis].axis_mode == AXIS_STANDARD ||
- mach.a[axis].axis_mode == AXIS_INHIBITED)
- return target[axis]; // no mm conversion - it's in degrees
+ switch (axes[axis].axis_mode) {
+ case AXIS_STANDARD:
+ case AXIS_INHIBITED:
+ return target[axis]; // no mm conversion - it's in degrees
- return TO_MILLIMETERS(target[axis]) * 360 / (2 * M_PI * mach.a[axis].radius);
+ default:
+ return TO_MILLIMETERS(target[axis]) * 360 / (2 * M_PI * axes[axis].radius);
+ }
}
// process XYZABC for lower modes
for (int axis = AXIS_X; axis <= AXIS_Z; axis++) {
- if (fp_FALSE(flag[axis]) || mach.a[axis].axis_mode == AXIS_DISABLED)
+ if (fp_FALSE(flag[axis]) || axes[axis].axis_mode == AXIS_DISABLED)
continue; // skip axis if not flagged for update or its disabled
- if (mach.a[axis].axis_mode == AXIS_STANDARD ||
- mach.a[axis].axis_mode == AXIS_INHIBITED) {
+ if (axes[axis].axis_mode == AXIS_STANDARD ||
+ axes[axis].axis_mode == AXIS_INHIBITED) {
if (mach.gm.distance_mode == ABSOLUTE_MODE)
mach.gm.target[axis] =
mach_get_active_coord_offset(axis) + TO_MILLIMETERS(target[axis]);
// NOTE: The ABC loop below relies on the XYZ loop having been run first
for (int axis = AXIS_A; axis <= AXIS_C; axis++) {
- if (fp_FALSE(flag[axis]) || mach.a[axis].axis_mode == AXIS_DISABLED)
+ if (fp_FALSE(flag[axis]) || axes[axis].axis_mode == AXIS_DISABLED)
continue; // skip axis if not flagged for update or its disabled
- else tmp = _calc_ABC(axis, target, flag);
+
+ tmp = _calc_ABC(axis, target, flag);
if (mach.gm.distance_mode == ABSOLUTE_MODE)
// sacidu93's fix to Issue #22
}
-/* Return error code if soft limit is exceeded
+/*** Return error code if soft limit is exceeded
*
* Must be called with target properly set in GM struct. Best done
* after mach_set_model_target().
for (int axis = 0; axis < AXES; axis++) {
if (!mach_get_homed(axis)) continue; // don't test axes that arent homed
- if (fp_EQ(mach.a[axis].travel_min, mach.a[axis].travel_max)) continue;
+ if (fp_EQ(axes[axis].travel_min, axes[axis].travel_max)) continue;
- if (mach.a[axis].travel_min > DISABLE_SOFT_LIMIT &&
- target[axis] < mach.a[axis].travel_min)
+ if (axes[axis].travel_min > DISABLE_SOFT_LIMIT &&
+ target[axis] < axes[axis].travel_min)
return STAT_SOFT_LIMIT_EXCEEDED;
- if (mach.a[axis].travel_max > DISABLE_SOFT_LIMIT &&
- target[axis] > mach.a[axis].travel_max)
+ if (axes[axis].travel_max > DISABLE_SOFT_LIMIT &&
+ target[axis] > axes[axis].travel_max)
return STAT_SOFT_LIMIT_EXCEEDED;
}
void machine_init() {
// Init 1/jerk
for (int axis = 0; axis < AXES; axis++)
- mach_set_axis_jerk(axis, mach.a[axis].jerk_max);
+ axes_set_jerk(axis, axes[axis].jerk_max);
// Set gcode defaults
mach_set_units(GCODE_DEFAULT_UNITS);
#include "config.h"
#include "status.h"
+#include "gcode_state.h"
#include <avr/pgmspace.h>
-#include <stdint.h>
-#include <stdbool.h>
-
#define TO_MILLIMETERS(a) (mach.gm.units == INCHES ? (a) * MM_PER_INCH : a)
-/* The difference between next_action_t and motion_mode_t is that
- * next_action_t is used by the current block, and may carry non-modal
- * commands, whereas motion_mode_t persists across blocks as G modal group 1
- */
-
-/// these are in order to optimized CASE statement
-typedef enum {
- NEXT_ACTION_DEFAULT, // Must be zero (invokes motion modes)
- NEXT_ACTION_SEARCH_HOME, // G28.2 homing cycle
- NEXT_ACTION_SET_ABSOLUTE_ORIGIN, // G28.3 origin set
- NEXT_ACTION_HOMING_NO_SET, // G28.4 homing cycle no coord setting
- NEXT_ACTION_SET_G28_POSITION, // G28.1 set position in abs coordinates
- NEXT_ACTION_GOTO_G28_POSITION, // G28 go to machine position
- NEXT_ACTION_SET_G30_POSITION, // G30.1
- NEXT_ACTION_GOTO_G30_POSITION, // G30
- NEXT_ACTION_SET_COORD_DATA, // G10
- NEXT_ACTION_SET_ORIGIN_OFFSETS, // G92
- NEXT_ACTION_RESET_ORIGIN_OFFSETS, // G92.1
- NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS, // G92.2
- NEXT_ACTION_RESUME_ORIGIN_OFFSETS, // G92.3
- NEXT_ACTION_DWELL, // G4
- NEXT_ACTION_STRAIGHT_PROBE, // G38.2
-} next_action_t;
-
-
-typedef enum { // G Modal Group 1
- MOTION_MODE_RAPID, // G0 - rapid
- MOTION_MODE_FEED, // G1 - straight feed
- MOTION_MODE_CW_ARC, // G2 - clockwise arc feed
- MOTION_MODE_CCW_ARC, // G3 - counter-clockwise arc feed
- MOTION_MODE_CANCEL_MOTION_MODE, // G80
- MOTION_MODE_STRAIGHT_PROBE, // G38.2
- MOTION_MODE_CANNED_CYCLE_81, // G81 - drilling
- MOTION_MODE_CANNED_CYCLE_82, // G82 - drilling with dwell
- MOTION_MODE_CANNED_CYCLE_83, // G83 - peck drilling
- MOTION_MODE_CANNED_CYCLE_84, // G84 - right hand tapping
- MOTION_MODE_CANNED_CYCLE_85, // G85 - boring, no dwell, feed out
- MOTION_MODE_CANNED_CYCLE_86, // G86 - boring, spindle stop, rapid out
- MOTION_MODE_CANNED_CYCLE_87, // G87 - back boring
- MOTION_MODE_CANNED_CYCLE_88, // G88 - boring, spindle stop, manual out
- MOTION_MODE_CANNED_CYCLE_89, // G89 - boring, dwell, feed out
-} motion_mode_t;
-
-
-typedef enum { // Used for detecting gcode errors. See NIST section 3.4
- MODAL_GROUP_G0, // {G10,G28,G28.1,G92} non-modal axis commands
- MODAL_GROUP_G1, // {G0,G1,G2,G3,G80} motion
- MODAL_GROUP_G2, // {G17,G18,G19} plane selection
- MODAL_GROUP_G3, // {G90,G91} distance mode
- MODAL_GROUP_G5, // {G93,G94} feed rate mode
- MODAL_GROUP_G6, // {G20,G21} units
- MODAL_GROUP_G7, // {G40,G41,G42} cutter radius compensation
- MODAL_GROUP_G8, // {G43,G49} tool length offset
- MODAL_GROUP_G9, // {G98,G99} return mode in canned cycles
- MODAL_GROUP_G12, // {G54,G55,G56,G57,G58,G59} coordinate system selection
- MODAL_GROUP_G13, // {G61,G61.1,G64} path control mode
- MODAL_GROUP_M4, // {M0,M1,M2,M30,M60} stopping
- MODAL_GROUP_M6, // {M6} tool change
- MODAL_GROUP_M7, // {M3,M4,M5} spindle turning
- MODAL_GROUP_M8, // {M7,M8,M9} coolant
- MODAL_GROUP_M9, // {M48,M49} speed/feed override switches
-} modal_group_t;
-
-#define MODAL_GROUP_COUNT (MODAL_GROUP_M9 + 1)
-
// Note 1: Our G0 omits G4, G30, G53, G92.1, G92.2, G92.3 as these have no axis
// components to error check
-typedef enum { // plane - translates to:
- // axis_0 axis_1 axis_2
- PLANE_XY, // G17 X Y Z
- PLANE_XZ, // G18 X Z Y
- PLANE_YZ, // G19 Y Z X
-} plane_t;
-
-
-typedef enum {
- INCHES, // G20
- MILLIMETERS, // G21
- DEGREES, // ABC axes (this value used for displays only)
-} units_t;
-
-
-typedef enum {
- ABSOLUTE_COORDS, // machine coordinate system
- G54, G55, G56, G57, G58, G59,
-} coord_system_t;
-
-/// G Modal Group 13
-typedef enum {
- PATH_EXACT_PATH, // G61 hits corners but stops only if needed
- PATH_EXACT_STOP, // G61.1 stops at all corners
- PATH_CONTINUOUS, // G64 and typically the default mode
-} path_mode_t;
-
-
-typedef enum {
- ABSOLUTE_MODE, // G90
- INCREMENTAL_MODE, // G91
-} distance_mode_t;
-
-
-typedef enum {
- INVERSE_TIME_MODE, // G93
- UNITS_PER_MINUTE_MODE, // G94
- UNITS_PER_REVOLUTION_MODE, // G95 (unimplemented)
-} feed_mode_t;
-
-
-typedef enum {
- ORIGIN_OFFSET_SET, // G92 - set origin offsets
- ORIGIN_OFFSET_CANCEL, // G92.1 - zero out origin offsets
- ORIGIN_OFFSET_SUSPEND, // G92.2 - do not apply offsets, but preserve values
- ORIGIN_OFFSET_RESUME, // G92.3 - resume application of the suspended offsets
-} origin_offset_t;
-
-
-typedef enum {
- PROGRAM_STOP,
- PROGRAM_OPTIONAL_STOP,
- PROGRAM_PALLET_CHANGE_STOP,
- PROGRAM_END,
-} program_flow_t;
-
-
-/// spindle state settings
-typedef enum {
- SPINDLE_OFF,
- SPINDLE_CW,
- SPINDLE_CCW,
-} spindle_mode_t;
-
-
-/// mist and flood coolant states
-typedef enum {
- COOLANT_OFF, // all coolant off
- COOLANT_ON, // request coolant on or indicate both coolants are on
- COOLANT_MIST, // indicates mist coolant on
- COOLANT_FLOOD, // indicates flood coolant on
-} coolant_state_t;
-
-
-/// used for spindle and arc dir
-typedef enum {
- DIRECTION_CW,
- DIRECTION_CCW,
-} direction_t;
-
-
-/// axis modes (ordered: see _mach_get_feed_time())
-typedef enum {
- AXIS_DISABLED, // kill axis
- AXIS_STANDARD, // axis in coordinated motion w/standard behaviors
- AXIS_INHIBITED, // axis is computed but not activated
- AXIS_RADIUS, // rotary axis calibrated to circumference
- AXIS_MODE_MAX,
-} axis_mode_t; // ordering must be preserved.
-
-
-/* Gcode model - The following GCodeModel/GCodeInput structs are used:
- *
- * - gm is the core Gcode model state. It keeps the internal gcode
- * state model in normalized, canonical form. All values are unit
- * converted (to mm) and in the machine coordinate system
- * (absolute coordinate system). Gm is owned by the machine layer and
- * should be accessed only through mach_ routines.
- *
- * - gn is used by the gcode interpreter and is re-initialized for
- * each gcode block.It accepts data in the new gcode block in the
- * formats present in the block (pre-normalized forms). During
- * initialization some state elements are necessarily restored
- * from gm.
- *
- * - gf is used by the gcode parser interpreter to hold flags for any
- * data that has changed in gn during the parse. parser.gf.target[]
- * values are also used by the machine during
- * set_target().
- */
-
-
-/// Gcode model state
-typedef struct {
- uint32_t line; // Gcode block line number
-
- uint8_t tool; // Tool after T and M6
- uint8_t tool_select; // T - sets this value
-
- float feed_rate; // F - in mm/min or inverse time mode
- feed_mode_t feed_mode;
- float feed_override_factor; // 1.0000 x F feed rate
- bool feed_override_enable; // M48, M49
-
- float spindle_speed; // in RPM
- spindle_mode_t spindle_mode;
- float spindle_override_factor; // 1.0000 x S spindle speed
- bool spindle_override_enable; // true = override enabled
-
- motion_mode_t motion_mode; // Group 1 modal motion
- plane_t plane; // G17, G18, G19
- units_t units; // G20, G21
- coord_system_t coord_system; // G54-G59 - select coordinate system 1-9
- bool absolute_mode; // G53 true = move in machine coordinates
- path_mode_t path_mode; // G61
- distance_mode_t distance_mode; // G91
- distance_mode_t arc_distance_mode; // G91.1
-
- bool mist_coolant; // true = mist on (M7), false = off (M9)
- bool flood_coolant; // true = mist on (M8), false = off (M9)
-
- next_action_t next_action; // handles G group 1 moves & non-modals
- program_flow_t program_flow; // used only by the gcode_parser
-
- // TODO unimplemented gcode parameters
- // float cutter_radius; // D - cutter radius compensation (0 is off)
- // float cutter_length; // H - cutter length compensation (0 is off)
-
- // Used for input only
- float target[AXES]; // XYZABC where the move should go
- bool override_enables; // feed and spindle enable
- bool tool_change; // M6 tool change flag
-
- float parameter; // P - dwell time in sec, G10 coord select
- float arc_radius; // R - radius value in arc radius mode
- float arc_offset[3]; // IJK - used by arc commands
-} gcode_state_t;
-
-
-typedef struct {
- axis_mode_t axis_mode;
- float feedrate_max; // max velocity in mm/min or deg/min
- float velocity_max; // max velocity in mm/min or deg/min
- float travel_max; // max work envelope for soft limits
- float travel_min; // min work envelope for soft limits
- float jerk_max; // max jerk (Jm) in mm/min^3 divided by 1 million
- float jerk_homing; // homing jerk (Jh) in mm/min^3 divided by 1 million
- float recip_jerk; // reciprocal of current jerk value - with million
- float junction_dev; // aka cornering delta
- float radius; // radius in mm for rotary axis modes
- float search_velocity; // homing search velocity
- float latch_velocity; // homing latch velocity
- float latch_backoff; // backoff from switches prior to homing latch movement
- float zero_backoff; // backoff from switches for machine zero
-} axis_config_t;
-
-
typedef struct { // struct to manage mach globals and cycles
float offset[COORDS + 1][AXES]; // coordinate systems & offsets G53-G59
float origin_offset[AXES]; // G92 offsets
float g28_position[AXES]; // stored machine position for G28
float g30_position[AXES]; // stored machine position for G30
- axis_config_t a[AXES]; // settings for axes
gcode_state_t gm; // core gcode model state
} machine_t;
void mach_set_absolute_mode(bool absolute_mode);
void mach_set_model_line(uint32_t line);
-float mach_get_axis_jerk(uint8_t axis);
-void mach_set_axis_jerk(uint8_t axis, float jerk);
-
// Coordinate systems and offsets
float mach_get_active_coord_offset(uint8_t axis);
void mach_update_work_offsets();
// Critical helpers
float mach_calc_move_time(const float axis_length[], const float axis_square[]);
-stat_t mach_deferred_write_callback();
void mach_set_model_target(float target[], float flag[]);
stat_t mach_test_soft_limits(float target[]);
#include "arc.h"
+#include "axes.h"
#include "buffer.h"
#include "line.h"
#include "gcode_parser.h"
mach_get_feed_rate() : length / mach_get_feed_rate();
// Downgrade the time if there is a rate-limiting axis
- return max4(time, planar_travel / mach.a[arc.plane_axis_0].feedrate_max,
- planar_travel / mach.a[arc.plane_axis_1].feedrate_max,
- fabs(linear_travel) / mach.a[arc.linear_axis].feedrate_max);
+ return max4(time, planar_travel / axes[arc.plane_axis_0].feedrate_max,
+ planar_travel / axes[arc.plane_axis_1].feedrate_max,
+ fabs(linear_travel) / axes[arc.linear_axis].feedrate_max);
}
#include "jog.h"
+#include "axes.h"
#include "planner.h"
#include "buffer.h"
#include "runtime.h"
// Compute new axis velocities and target
for (int axis = 0; axis < AXES; axis++) {
- float target_v = jr.target_velocity[axis] * mach.a[axis].velocity_max;
+ float target_v = jr.target_velocity[axis] * axes[axis].velocity_max;
float delta_v = target_v - jr.current_velocity[axis];
float sign = delta_v < 0 ? -1 : 1;
#include "line.h"
+#include "axes.h"
#include "planner.h"
#include "exec.h"
#include "runtime.h"
float b_delta = 0;
for (int axis = 0; axis < AXES; axis++) {
- a_delta += square(a_unit[axis] * mach.a[axis].junction_dev);
- b_delta += square(b_unit[axis] * mach.a[axis].junction_dev);
+ a_delta += square(a_unit[axis] * axes[axis].junction_dev);
+ b_delta += square(b_unit[axis] * axes[axis].junction_dev);
}
float delta = (sqrt(a_delta) + sqrt(b_delta)) / 2;
for (int axis = 0; axis < AXES; axis++)
if (axis_square[axis]) { // Do not use fp_ZERO here
// Squaring axis_length ensures it's positive
- C = axis_square[axis] * mach.a[axis].recip_jerk;
+ C = axis_square[axis] * axes[axis].recip_jerk;
if (maxC < C) {
maxC = C;
// vector term. This way when the move is finally decomposed into
// its constituent axes for execution the jerk for that axis will be
// at it's maximum value.
- return mach.a[jerk_axis].jerk_max * JERK_MULTIPLIER / fabs(unit[jerk_axis]);
+ return axes[jerk_axis].jerk_max * JERK_MULTIPLIER / fabs(unit[jerk_axis]);
}
#include "planner.h"
+#include "axes.h"
#include "buffer.h"
#include "machine.h"
#include "stepper.h"
// account.
for (int motor = 0; motor < MOTORS; motor++) {
int axis = motor_get_axis(motor);
- if (mach.a[axis].axis_mode == AXIS_INHIBITED) steps[motor] = 0;
+ if (axes[axis].axis_mode == AXIS_INHIBITED) steps[motor] = 0;
else steps[motor] = travel[axis] * motor_get_steps_per_unit(motor);
}
}
\******************************************************************************/
#include "machine.h"
+#include "axes.h"
#include "spindle.h"
#include "switch.h"
#include "util.h"
// restore axis jerk
for (int axis = 0; axis < AXES; axis++ )
- mach_set_axis_jerk(axis, pb.saved_jerk[axis]);
+ axes_set_jerk(axis, pb.saved_jerk[axis]);
// restore coordinate system and distance mode
mach_set_coord_system(pb.saved_coord_system);
// initialize the axes - save the jerk settings & switch to the jerk_homing
// settings
for (int axis = 0; axis < AXES; axis++) {
- pb.saved_jerk[axis] = mach_get_axis_jerk(axis); // save the max jerk value
+ pb.saved_jerk[axis] = axes_get_jerk(axis); // save the max jerk value
// use homing jerk for probe
- mach_set_axis_jerk(axis, mach.a[axis].jerk_homing);
+ axes_set_jerk(axis, axes[axis].jerk_homing);
pb.start_position[axis] = mach_get_absolute_position(axis);
}