static const char *handle_z_probe(struct GCodeParser *p, const char *line) { char letter; float value; float feedrate = -1; float probe_thickness = 0; const char *remaining_line; while ((remaining_line = gparse_pair(p, line, &letter, &value))) { const float unit_value = value * p->unit_to_mm_factor; if (letter == 'F') feedrate = f_param_to_feedrate(unit_value); else if (letter == 'Z') probe_thickness = value * p->unit_to_mm_factor; else break; line = remaining_line; } // Probe for the travel endstop float probed_pos; if (p->callbacks.probe_axis(p->callbacks.user_data, feedrate, AXIS_Z, &probed_pos)) { p->axes_pos[AXIS_Z] = probed_pos; // Doing implicit G92 here. Is this what we want ? Later, this might // be part of tool-offset or something. p->global_offset_g92[AXIS_Z] = (p->axes_pos[AXIS_Z] - probe_thickness) - p->current_origin[AXIS_Z]; set_current_origin(p, p->current_origin, p->global_offset_g92); } return line; }
// For we just generate an arc by emitting many small steps for // now. TODO(hzeller): actually generate a curve profile for that. // With G17, G18, G19, the plane was selected before. // X, Y, Z: new position (two in the plane, one for the helix. // I, J, K: offset to center, corresponding to X,Y,Z. // Only the two in the given plane are relevant. // F : Optional feedrate. // P : number of turns. currently ignored. // R : TODO: implement. Modern systems allow that. static const char *handle_arc(struct GCodeParser *p, const char *line, int is_cw) { const char *remaining_line; float target[GCODE_NUM_AXES]; float offset[GCODE_NUM_AXES] = {0}; float feedrate = -1; float value; char letter; int turns = 1; memcpy(target, p->axes_pos, GCODE_NUM_AXES * sizeof(*target)); while ((remaining_line = gparse_pair(p, line, &letter, &value))) { const float unit_value = value * p->unit_to_mm_factor; if (letter == 'X') target[AXIS_X] = abs_axis_pos(p, AXIS_X, unit_value); else if (letter == 'Y') target[AXIS_Y] = abs_axis_pos(p, AXIS_Y, unit_value); else if (letter == 'Z') target[AXIS_Z] = abs_axis_pos(p, AXIS_Z, unit_value); else if (letter == 'I') offset[AXIS_X] = unit_value; else if (letter == 'J') offset[AXIS_Y] = unit_value; else if (letter == 'K') offset[AXIS_Z] = unit_value; else if (letter == 'F') feedrate = f_param_to_feedrate(unit_value); else if (letter == 'P') turns = (int)value; // currently ignored // TODO: 'R' else break; line = remaining_line; } // Should the arc parameters be sanity checked? if (turns < 0 || turns > 4) { fprintf(stderr, "G-Code Syntax Error: handle_arc: turns=%d (must be 1-4)\n", turns); return remaining_line; } struct ArcCallbackData cb_arc_data; cb_arc_data.parser = p; cb_arc_data.feedrate = feedrate; arc_gen(p->arc_normal, is_cw, p->axes_pos, offset, target, &arc_callback, &cb_arc_data); return line; }
static const char *handle_move(struct GCodeParser *p, const char *line, int force_change) { char axis_l; float value; int any_change = force_change; float feedrate = -1; const char *remaining_line; AxesRegister new_pos; memcpy(new_pos, p->axes_pos, sizeof(new_pos)); while ((remaining_line = gparse_pair(p, line, &axis_l, &value))) { const float unit_value = value * p->unit_to_mm_factor; if (axis_l == 'F') { feedrate = f_param_to_feedrate(unit_value); any_change = 1; } else { const enum GCodeParserAxis update_axis = gcodep_letter2axis(axis_l); if (update_axis == GCODE_NUM_AXES) break; // Invalid axis: possibly start of new command. new_pos[update_axis] = abs_axis_pos(p, update_axis, unit_value); any_change = 1; } line = remaining_line; } char did_move = 0; if (any_change) { if (p->modal_g0_g1) { did_move = p->callbacks.coordinated_move(p->callbacks.user_data, feedrate, new_pos); } else { did_move = p->callbacks.rapid_move(p->callbacks.user_data, feedrate, new_pos); } } if (did_move) { memcpy(p->axes_pos, new_pos, sizeof(p->axes_pos)); } return line; }