#include "gcode_parser.h"
#include "machine.h"
-#include "spindle.h"
+#include "plan/arc.h"
#include "probing.h"
#include "homing.h"
#include "util.h"
/* Gcode model
*
- * - gm is the core Gcode model state. It keeps the internal gcode
+ * - mach.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.
+ * should be accessed only through mach_*() routines.
*
- * - gn is used by the gcode parser and is re-initialized for
+ * - parser.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().
+ * - parser.gf is used by the gcode parser to hold flags for any data that has
+ * changed in gn during the parse.
*/
#include "machine.h"
#include "switch.h"
#include "gcode_parser.h"
-#include "util.h"
#include "report.h"
#include "plan/planner.h"
#include "plan/runtime.h"
#include "plan/state.h"
-#include <avr/pgmspace.h>
-
-#include <stdbool.h>
-#include <math.h>
-#include <stdio.h>
-
typedef void (*homing_func_t)(int8_t axis);
float max_clear_backoff;
// state saved from gcode model
- uint8_t saved_units; // G20,G21 global setting
+ uint8_t saved_units; // G20,G21 global setting
uint8_t saved_coord_system; // G54 - G59 setting
uint8_t saved_distance_mode; // G90,G91 global setting
- uint8_t saved_feed_mode; // G93,G94 global setting
+ uint8_t saved_feed_mode; // G93,G94 global setting
float saved_feed_rate; // F setting
float saved_jerk; // saved and restored for each axis homed
} homing_t;
* When a homing cycle is initiated the homing state is set to HOMING_NOT_HOMED
* When homing completes successfully this is set to HOMING_HOMED, otherwise it
* remains HOMING_NOT_HOMED.
- */
-/* --- Some further details ---
*
- * Note: When coding a cycle (like this one) you get to perform one queued
- * move per entry into the continuation, then you must exit.
+ * Notes:
+ *
+ * 1. When coding a cycle (like this one) you get to perform one queued
+ * move per entry into the continuation, then you must exit.
*
- * Another Note: When coding a cycle (like this one) you must wait until
- * the last move has actually been queued (or has finished) before declaring
- * the cycle to be done. Otherwise there is a nasty race condition
- * that will accept the next command before the position of
- * the final move has been recorded in the Gcode model. That's what the call
- * to mach_is_busy() is about.
+ * 2. When coding a cycle (like this one) you must wait until
+ * the last move has actually been queued (or has finished) before
+ * declaring the cycle to be done. Otherwise there is a nasty race
+ * condition that will accept the next command before the position of
+ * the final move has been recorded in the Gcode model.
*/
-/* Return next axis in sequence based on axis in arg
+/*** Return next axis in sequence based on axis in arg
*
* Accepts "axis" arg as the current axis; or -1 to retrieve the first axis
* Returns next axis based on "axis" argument and if that axis is flagged for
#include "gcode_parser.h"
#include "spindle.h"
#include "coolant.h"
-#include "switch.h"
-#include "hardware.h"
-#include "util.h"
-#include "report.h"
#include "homing.h"
-#include "gcode_state.h"
#include "plan/planner.h"
#include "plan/runtime.h"
#include "plan/line.h"
#include "plan/state.h"
-#include <stdbool.h>
-#include <string.h>
-#include <math.h>
-#include <stdio.h>
-
#define DISABLE_SOFT_LIMIT -1000000
// Free Space Motion (4.3.4)
-
-/// G0 linear rapid
-stat_t mach_rapid(float values[], bool flags[]) {
- mach.gm.motion_mode = MOTION_MODE_RAPID;
-
+static stat_t _feed(float values[], bool flags[]) {
float target[AXES];
mach_calc_model_target(target, values, flags);
if (status != STAT_OK) return ALARM(status);
// prep and plan the move
- mach_update_work_offsets(); // update resolved offsets
+ mach_update_work_offsets(); // update resolved offsets
status = mp_aline(target, mach_get_line()); // send move to planner
copy_vector(mach.position, target); // update model position
}
+/// G0 linear rapid
+stat_t mach_rapid(float values[], bool flags[]) {
+ mach.gm.motion_mode = MOTION_MODE_RAPID;
+ return _feed(values, flags);
+}
+
+
/// G28.1
void mach_set_g28_position() {copy_vector(mach.g28_position, mach.position);}
return STAT_GCODE_FEEDRATE_NOT_SPECIFIED;
mach.gm.motion_mode = MOTION_MODE_FEED;
-
- float target[AXES];
- mach_calc_model_target(target, values, flags);
-
- // test soft limits
- stat_t status = mach_test_soft_limits(target);
- if (status != STAT_OK) return ALARM(status);
-
- // prep and plan the move
- mach_update_work_offsets(); // update resolved offsets
- status = mp_aline(target, mach_get_line()); // send move to planner
- copy_vector(mach.position, target); // update model position
-
- return status;
+ return _feed(values, flags);
}
void mach_set_feed_mode(feed_mode_t mode);
void mach_set_path_mode(path_mode_t mode);
-// Machining Functions (4.3.6)
+// Machining Functions (4.3.6) see arc.h
stat_t mach_feed(float target[], bool flags[]);
-stat_t mach_arc_feed(float target[], bool flags[], float offsets[],
- bool offset_f[], float radius, bool radius_f,
- float P, bool P_f, bool modal_g1_f, uint8_t motion_mode);
stat_t mach_dwell(float seconds);
// Spindle Functions (4.3.7) see spindle.h
* Assumes arc singleton has been pre-loaded with target and position.
* Parts of this routine were originally sourced from the grbl project.
*/
-static stat_t _compute_arc_offsets_from_radius(float offset[]) {
+static stat_t _compute_arc_offsets_from_radius(float offset[], bool clockwise) {
// Calculate the change in position along each selected axis
float x =
arc.target[arc.plane_axis_0] - mach_get_axis_position(arc.plane_axis_0);
float h_x2_div_d = disc > 0 ? -sqrt(disc) / hypotf(x, y) : 0;
// Invert sign of h_x2_div_d if circle is counter clockwise (see header notes)
- if (mach_get_motion_mode() == MOTION_MODE_CCW_ARC) h_x2_div_d = -h_x2_div_d;
+ if (!clockwise) h_x2_div_d = -h_x2_div_d;
// Negative R is g-code-alese for "I want a circle with more than 180 degrees
// of travel" (go figure!), even though it is advised against ever generating
* Parts of this routine were originally sourced from the grbl project.
*/
static stat_t _compute_arc(bool radius_f, const float position[],
- float offset[], float rotations, bool full_circle) {
+ float offset[], float rotations, bool clockwise,
+ bool full_circle) {
// Compute radius. A non-zero radius value indicates a radius arc
- if (radius_f) _compute_arc_offsets_from_radius(offset);
+ if (radius_f) _compute_arc_offsets_from_radius(offset, clockwise);
else // compute start radius
arc.radius = hypotf(-offset[arc.plane_axis_0], -offset[arc.plane_axis_1]);
angular_travel = theta_end - arc.theta;
// reverse travel direction if it's CCW arc
- if (mach_get_motion_mode() == MOTION_MODE_CCW_ARC)
- angular_travel -= 2 * M_PI * g18_correction;
+ if (!clockwise) angular_travel -= 2 * M_PI * g18_correction;
}
}
// Add in travel for rotations
- if (mach_get_motion_mode() == MOTION_MODE_CW_ARC)
- angular_travel += 2 * M_PI * rotations * g18_correction;
+ if (clockwise) angular_travel += 2 * M_PI * rotations * g18_correction;
else angular_travel -= 2 * M_PI * rotations * g18_correction;
// Calculate travel in the depth axis of the helix and compute the time it
float radius, bool radius_f, // radius
float P, bool P_f, // parameter
bool modal_g1_f,
- uint8_t motion_mode) { // defined motion mode
+ motion_mode_t motion_mode) { // defined motion mode
// Trap some precursor cases. Since motion mode (MODAL_GROUP_G1) persists
// from the previous move it's possible for non-modal commands such as F or P
break;
}
+ bool clockwise = motion_mode == MOTION_MODE_CW_ARC;
+
// Test if endpoints are specified in the selected plane
bool full_circle = false;
if (!values_f[arc.plane_axis_0] && !values_f[arc.plane_axis_1]) {
}
// compute arc runtime values
- RITORNO(_compute_arc(radius_f, position, offset, rotations, full_circle));
+ RITORNO(_compute_arc
+ (radius_f, position, offset, rotations, clockwise, full_circle));
// Note, arc soft limits are not tested here
#pragma once
-#include <stdbool.h>
+#include "gcode_state.h"
+#include "status.h"
#define ARC_SEGMENT_LENGTH 0.1 // mm
#define MIN_ARC_SEGMENT_TIME (MIN_ARC_SEGMENT_USEC / MICROSECONDS_PER_MINUTE)
+stat_t mach_arc_feed(float target[], bool flags[], float offsets[],
+ bool offset_f[], float radius, bool radius_f,
+ float P, bool P_f, bool modal_g1_f,
+ motion_mode_t motion_mode);
void mach_arc_callback();
bool mach_arc_active();
void mach_abort_arc();