#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string>
#include "rtapi_math.h"
#include "rs274ngc.hh"
#include "rs274ngc_return.hh"
#include "rs274ngc_interp.hh"
#include "interp_internal.hh"
#include "interp_queue.hh"
#include "interp_parameter_def.hh"
#include "units.h"
#define TOOL_INSIDE_ARC(side, turn) (((side)==LEFT&&(turn)>0)||((side)==RIGHT&&(turn)<0))
#define DEBUG_EMC
using namespace interp_param_global;
int Interp::comp_get_current(setup_pointer settings, double *x, double *y, double *z) {
switch(settings->plane) {
case CANON_PLANE_XY:
*x = settings->current_x;
*y = settings->current_y;
*z = settings->current_z;
break;
case CANON_PLANE_XZ:
*x = settings->current_z;
*y = settings->current_x;
*z = settings->current_y;
break;
default:
ERS("BUG: Invalid plane in comp_get_current");
}
return INTERP_OK;
}
int Interp::comp_set_current(setup_pointer settings, double x, double y, double z) {
switch(settings->plane) {
case CANON_PLANE_XY:
settings->current_x = x;
settings->current_y = y;
settings->current_z = z;
break;
case CANON_PLANE_XZ:
settings->current_x = y;
settings->current_y = z;
settings->current_z = x;
break;
default:
ERS("BUG: Invalid plane in comp_set_current");
}
return INTERP_OK;
}
int Interp::comp_get_programmed(setup_pointer settings, double *x, double *y, double *z) {
switch(settings->plane) {
case CANON_PLANE_XY:
*x = settings->program_x;
*y = settings->program_y;
*z = settings->program_z;
break;
case CANON_PLANE_XZ:
*x = settings->program_z;
*y = settings->program_x;
*z = settings->program_y;
break;
default:
ERS("BUG: Invalid plane in comp_get_programmed");
}
return INTERP_OK;
}
int Interp::comp_set_programmed(setup_pointer settings, double x, double y, double z) {
switch(settings->plane) {
case CANON_PLANE_XY:
settings->program_x = x;
settings->program_y = y;
settings->program_z = z;
break;
case CANON_PLANE_XZ:
settings->program_x = y;
settings->program_y = z;
settings->program_z = x;
break;
default:
ERS("BUG: Invalid plane in comp_set_programmed");
}
return INTERP_OK;
}
static unsigned int nurbs_order;
static std::vector<CONTROL_POINT> nurbs_control_points;
int Interp::convert_nurbs(int mode,
block_pointer block, setup_pointer settings) {
double end_z, AA_end, BB_end, CC_end, u_end, v_end, w_end;
CONTROL_POINT CP;
if (mode == G_5_2) {
CHKS((((block->x_flag) && !(block->y_flag)) || (!(block->x_flag) && (block->y_flag))), (
_("You must specify both X and Y coordinates for Control Points")));
CHKS((!(block->x_flag) && !(block->y_flag) && (block->p_number > 0) &&
(!nurbs_control_points.empty())), (
_("Can specify P without X and Y only for the first control point")));
CHKS(((block->p_number <= 0) && (!nurbs_control_points.empty())), (
_("Must specify positive weight P for every Control Point")));
if (settings->feed_mode == UNITS_PER_MINUTE) {
CHKS((settings->feed_rate == 0.0), (
_("Cannot make a NURBS with 0 feedrate")));
}
if (settings->motion_mode != mode) nurbs_control_points.clear();
if (nurbs_control_points.empty()) {
CP.X = settings->current_x;
CP.Y = settings->current_y;
if (!(block->x_flag) && !(block->y_flag) && (block->p_number > 0)) {
CP.W = block->p_number;
} else {
CP.W = 1;
}
nurbs_order = 3;
nurbs_control_points.push_back(CP);
}
if (block->l_number != -1 && block->l_number > 3) {
nurbs_order = block->l_number;
}
if ((block->x_flag) && (block->y_flag)) {
CHP(find_ends(block, settings, &CP.X, &CP.Y, &end_z, &AA_end, &BB_end, &CC_end,
&u_end, &v_end, &w_end));
CP.W = block->p_number;
nurbs_control_points.push_back(CP);
}
settings->motion_mode = mode;
}
else if (mode == G_5_3){
CHKS((settings->motion_mode != G_5_2), (
_("Cannot use G5.3 without G5.2 first")));
CHKS((nurbs_control_points.size()<nurbs_order), _("You must specify a number of control points at least equal to the order L = %d"), nurbs_order);
settings->current_x = nurbs_control_points[nurbs_control_points.size()-1].X;
settings->current_y = nurbs_control_points[nurbs_control_points.size()-1].Y;
NURBS_FEED(block->line_number, nurbs_control_points, nurbs_order);
nurbs_control_points.clear();
settings->motion_mode = -1;
}
return INTERP_OK;
}
int Interp::convert_spline(int mode,
block_pointer block, setup_pointer settings) {
double x1, y1, x2, y2, x3, y3;
double end_z, AA_end, BB_end, CC_end, u_end, v_end, w_end;
CONTROL_POINT cp;
CHKS((settings->cutter_comp_side), _("Cannot convert spline with cutter radius compensation"));
if (settings->feed_mode == UNITS_PER_MINUTE) {
CHKS((settings->feed_rate == 0.0),
NCE_CANNOT_MAKE_ARC_WITH_ZERO_FEED_RATE);
} else if (settings->feed_mode == INVERSE_TIME) {
CHKS((!block->f_flag),
NCE_F_WORD_MISSING_WITH_INVERSE_TIME_ARC_MOVE);
}
CHKS((settings->plane != CANON_PLANE_XY), _("Splines must be in the XY plane"));
CHKS((block->z_flag || block->a_flag || block->b_flag
|| block->c_flag),
_("Splines may not have motion in Z, A, B, or C"));
if(mode == G_5_1) {
CHKS(!block->i_flag || !block->j_flag,
_("Must specify both I and J with G5.1"));
x1 = settings->current_x + block->i_number;
y1 = settings->current_y + block->j_number;
CHP(find_ends(block, settings, &x2, &y2, &end_z, &AA_end, &BB_end, &CC_end,
&u_end, &v_end, &w_end));
cp.W = 1;
cp.X = settings->current_x;
cp.Y = settings->current_y;
nurbs_control_points.push_back(cp);
cp.X = x1;
cp.Y = y1;
nurbs_control_points.push_back(cp);
cp.X = x2;
cp.Y = y2;
nurbs_control_points.push_back(cp);
NURBS_FEED(block->line_number, nurbs_control_points, 3);
nurbs_control_points.clear();
settings->current_x = x2;
settings->current_y = y2;
} else {
if(!block->i_flag || !block->j_flag) {
CHKS(block->i_flag || block->j_flag,
_("Must specify both I and J, or neither"));
x1 = settings->current_x + settings->cycle_i;
y1 = settings->current_y + settings->cycle_j;
} else {
x1 = settings->current_x + block->i_number;
y1 = settings->current_y + block->j_number;
}
CHP(find_ends(block, settings, &x3, &y3, &end_z, &AA_end, &BB_end, &CC_end,
&u_end, &v_end, &w_end));
CHKS(!block->p_flag || !block->q_flag,
_("Must specify both P and Q with G5"));
x2 = x3 + block->p_number;
y2 = y3 + block->q_number;
cp.W = 1;
cp.X = settings->current_x;
cp.Y = settings->current_y;
nurbs_control_points.push_back(cp);
cp.X = x1;
cp.Y = y1;
nurbs_control_points.push_back(cp);
cp.X = x2;
cp.Y = y2;
nurbs_control_points.push_back(cp);
cp.X = x3;
cp.Y = y3;
nurbs_control_points.push_back(cp);
NURBS_FEED(block->line_number, nurbs_control_points, 4);
nurbs_control_points.clear();
settings->cycle_i = -block->p_number;
settings->cycle_j = -block->q_number;
settings->current_x = x3;
settings->current_y = y3;
}
return INTERP_OK;
}
int Interp::convert_arc(int move, block_pointer block, setup_pointer settings) {
int status;
int first;
int ijk_flag;
double end_x;
double end_y;
double end_z;
double AA_end;
double BB_end;
double CC_end;
double u_end, v_end, w_end;
CHKS((settings->arc_not_allowed), (_("The move just after exiting cutter compensation mode must be straight, not an arc")));
ijk_flag = block->i_flag || block->j_flag || block->k_flag;
first = settings->cutter_comp_firstmove;
CHKS((settings->plane == CANON_PLANE_UV
|| settings->plane == CANON_PLANE_VW
|| settings->plane == CANON_PLANE_UW),
_("Cannot do an arc in planes G17.1, G18.1, or G19.1"));
CHKS(((!block->r_flag) && (!ijk_flag)),
NCE_R_I_J_K_WORDS_ALL_MISSING_FOR_ARC);
CHKS(((block->r_flag) && (ijk_flag)),
NCE_MIXED_RADIUS_IJK_FORMAT_FOR_ARC);
if (settings->feed_mode == UNITS_PER_MINUTE) {
CHKS((settings->feed_rate == 0.0),
NCE_CANNOT_MAKE_ARC_WITH_ZERO_FEED_RATE);
} else if(settings->feed_mode == UNITS_PER_REVOLUTION) {
CHKS((settings->feed_rate == 0.0),
NCE_CANNOT_MAKE_ARC_WITH_ZERO_FEED_RATE);
CHKS((settings->speed[settings->active_spindle] == 0.0),
_("Cannot feed with zero spindle speed in feed per rev mode"));
} else if (settings->feed_mode == INVERSE_TIME) {
CHKS((!block->f_flag),
NCE_F_WORD_MISSING_WITH_INVERSE_TIME_ARC_MOVE);
}
if (ijk_flag) {
if (settings->plane == CANON_PLANE_XY) {
CHKS((block->k_flag), NCE_K_WORD_GIVEN_FOR_ARC_IN_XY_PLANE);
if (!block->i_flag) {
if (settings->ijk_distance_mode == MODE_ABSOLUTE) {
ERS(_("%c word missing in absolute center arc"), 'I');
} else {
block->i_number = 0.0;
}
} else if (!block->j_flag) {
if (settings->ijk_distance_mode == MODE_ABSOLUTE) {
ERS(_("%c word missing in absolute center arc"), 'J');
} else {
block->j_number = 0.0;
}
}
} else if (settings->plane == CANON_PLANE_YZ) {
CHKS((block->i_flag), NCE_I_WORD_GIVEN_FOR_ARC_IN_YZ_PLANE);
if (!block->j_flag) {
if (settings->ijk_distance_mode == MODE_ABSOLUTE) {
ERS(_("%c word missing in absolute center arc"), 'J');
} else {
block->j_number = 0.0;
}
} else if (!block->k_flag) {
if (settings->ijk_distance_mode == MODE_ABSOLUTE) {
ERS(_("%c word missing in absolute center arc"), 'K');
} else {
block->k_number = 0.0;
}
}
} else if (settings->plane == CANON_PLANE_XZ) {
CHKS((block->j_flag), NCE_J_WORD_GIVEN_FOR_ARC_IN_XZ_PLANE);
if (!block->i_flag) {
if (settings->ijk_distance_mode == MODE_ABSOLUTE) {
ERS(_("%c word missing in absolute center arc"), 'I');
} else {
block->i_number = 0.0;
}
} else if (!block->k_flag) {
if (settings->ijk_distance_mode == MODE_ABSOLUTE) {
ERS(_("%c word missing in absolute center arc"), 'K');
} else {
block->k_number = 0.0;
}
}
} else {
ERS(NCE_BUG_PLANE_NOT_XY_YZ_OR_XZ);
}
} else {
if (settings->plane == CANON_PLANE_XY) {
CHKS(((!block->x_flag) && (!block->y_flag) && (!block->radius_flag) && (!block->theta_flag)),
NCE_X_AND_Y_WORDS_MISSING_FOR_ARC_IN_XY_PLANE);
} else if (settings->plane == CANON_PLANE_YZ) {
CHKS(((!block->y_flag) && (!block->z_flag)),
NCE_Y_AND_Z_WORDS_MISSING_FOR_ARC_IN_YZ_PLANE);
} else if (settings->plane == CANON_PLANE_XZ) {
CHKS(((!block->x_flag) && (!block->z_flag)),
NCE_X_AND_Z_WORDS_MISSING_FOR_ARC_IN_XZ_PLANE);
}
}
CHP(find_ends(block, settings, &end_x, &end_y, &end_z,
&AA_end, &BB_end, &CC_end,
&u_end, &v_end, &w_end));
settings->motion_mode = move;
if (settings->plane == CANON_PLANE_XY) {
if ((!settings->cutter_comp_side) ||
(settings->cutter_comp_radius == 0.0)) {
status =
convert_arc2(move, block, settings,
&(settings->current_x), &(settings->current_y),
&(settings->current_z), end_x, end_y, end_z,
AA_end, BB_end, CC_end,
u_end, v_end, w_end,
block->i_number, block->j_number);
CHP(status);
} else if (first) {
status = convert_arc_comp1(move, block, settings, end_x, end_y, end_z,
block->i_number, block->j_number,
AA_end, BB_end, CC_end,
u_end, v_end, w_end);
CHP(status);
} else {
status = convert_arc_comp2(move, block, settings, end_x, end_y, end_z,
block->i_number, block->j_number,
AA_end, BB_end, CC_end,
u_end, v_end, w_end);
CHP(status);
}
} else if (settings->plane == CANON_PLANE_XZ) {
if ((!settings->cutter_comp_side) ||
(settings->cutter_comp_radius == 0.0)) {
status =
convert_arc2(move, block, settings,
&(settings->current_z), &(settings->current_x),
&(settings->current_y), end_z, end_x, end_y,
AA_end, BB_end, CC_end,
u_end, v_end, w_end,
block->k_number, block->i_number);
CHP(status);
} else if (first) {
status = convert_arc_comp1(move, block, settings, end_z, end_x, end_y,
block->k_number, block->i_number,
AA_end, BB_end, CC_end,
u_end, v_end, w_end);
CHP(status);
} else {
status = convert_arc_comp2(move, block, settings, end_z, end_x, end_y,
block->k_number, block->i_number,
AA_end, BB_end, CC_end,
u_end, v_end, w_end);
CHP(status);
}
} else if (settings->plane == CANON_PLANE_YZ) {
status =
convert_arc2(move, block, settings,
&(settings->current_y), &(settings->current_z),
&(settings->current_x), end_y, end_z, end_x,
AA_end, BB_end, CC_end,
u_end, v_end, w_end,
block->j_number, block->k_number);
CHP(status);
} else
ERS(NCE_BUG_PLANE_NOT_XY_YZ_OR_XZ);
return INTERP_OK;
}
int Interp::convert_arc2(int move, block_pointer block, setup_pointer settings, double *current1, double *current2, double *current3, double end1, double end2, double end3, double AA_end, double BB_end, double CC_end, double u, double v, double w, double offset1, double offset2)
{
double center1;
double center2;
int turn;
int plane = settings->plane;
double spiral_abs_tolerance = (settings->length_units == CANON_UNITS_INCHES) ?
settings->center_arc_radius_tolerance_inch : settings->center_arc_radius_tolerance_mm;
double radius_tolerance = (settings->length_units == CANON_UNITS_INCHES) ?
RADIUS_TOLERANCE_INCH : RADIUS_TOLERANCE_MM;
if (block->r_flag) {
CHP(arc_data_r(move, plane, *current1, *current2, end1, end2,
block->r_number, block->p_flag? round_to_int(block->p_number) : 1,
¢er1, ¢er2, &turn, radius_tolerance));
} else {
CHP(arc_data_ijk(move, plane, *current1, *current2, end1, end2,
(settings->ijk_distance_mode == MODE_ABSOLUTE),
offset1, offset2, block->p_flag? round_to_int(block->p_number) : 1,
¢er1, ¢er2, &turn, radius_tolerance, spiral_abs_tolerance, SPIRAL_RELATIVE_TOLERANCE));
}
inverse_time_rate_arc(*current1, *current2, *current3, center1, center2,
turn, end1, end2, end3, block, settings);
ARC_FEED(block->line_number, end1, end2, center1, center2, turn, end3,
AA_end, BB_end, CC_end, u, v, w);
*current1 = end1;
*current2 = end2;
*current3 = end3;
settings->AA_current = AA_end;
settings->BB_current = BB_end;
settings->CC_current = CC_end;
settings->u_current = u;
settings->v_current = v;
settings->w_current = w;
return INTERP_OK;
}
int Interp::convert_arc_comp1(int move, block_pointer block, setup_pointer settings, double end_x, double end_y, double end_z, double offset_x, double offset_y,
double AA_end, double BB_end, double CC_end, double u_end, double v_end, double w_end) {
double center_x, center_y;
double gamma;
int side;
double tool_radius;
int turn;
double cx, cy, cz; int plane = settings->plane;
side = settings->cutter_comp_side;
tool_radius = settings->cutter_comp_radius;
double spiral_abs_tolerance = (settings->length_units == CANON_UNITS_INCHES) ? settings->center_arc_radius_tolerance_inch : settings->center_arc_radius_tolerance_mm;
double radius_tolerance = (settings->length_units == CANON_UNITS_INCHES) ? RADIUS_TOLERANCE_INCH : RADIUS_TOLERANCE_MM;
comp_get_current(settings, &cx, &cy, &cz);
CHKS((hypot((end_x - cx), (end_y - cy)) <= tool_radius),
_("Radius of cutter compensation entry arc is not greater than the tool radius"));
if (block->r_flag) {
CHP(arc_data_comp_r(move, plane, side, tool_radius, cx, cy, end_x, end_y,
block->r_number, block->p_flag? round_to_int(block->p_number): 1,
¢er_x, ¢er_y, &turn, radius_tolerance));
} else {
CHP(arc_data_comp_ijk(move, plane, side, tool_radius, cx, cy, end_x, end_y,
(settings->ijk_distance_mode == MODE_ABSOLUTE),
offset_x, offset_y, block->p_flag? round_to_int(block->p_number): 1,
¢er_x, ¢er_y, &turn, radius_tolerance, spiral_abs_tolerance, SPIRAL_RELATIVE_TOLERANCE));
}
inverse_time_rate_arc(cx, cy, cz, center_x, center_y,
turn, end_x, end_y, end_z, block, settings);
if TOOL_INSIDE_ARC(side, turn) {
gamma = atan2((center_y - end_y), (center_x - end_x));
} else {
gamma = atan2((end_y - center_y), (end_x - center_x));
}
settings->cutter_comp_firstmove = false;
comp_set_programmed(settings, end_x, end_y, end_z);
end_x += tool_radius * cos(gamma);
end_y += tool_radius * sin(gamma);
double b_len = hypot(cy - end_y, cx - end_x) / 2.0;
double AB_ang = atan2(center_y - end_y, center_x - end_x);
double A_ang = atan2(cy - end_y, cx - end_x) - AB_ang;
CHKS((fabs(cos(A_ang)) < TOLERANCE_EQUAL), NCE_TOOL_RADIUS_NOT_LESS_THAN_ARC_RADIUS_WITH_COMP);
double c_len = b_len/cos(A_ang);
center_x = end_x + c_len * cos(AB_ang);
center_y = end_y + c_len * sin(AB_ang);
CHKS((fabs(hypot(center_x-end_x,center_y-end_y) -
hypot(center_x-cx,center_y-cy)) > spiral_abs_tolerance),
NCE_BUG_IN_TOOL_RADIUS_COMP);
if (settings->cutter_comp_orientation != 0 && settings->cutter_comp_orientation != 9) {
enqueue_STRAIGHT_FEED(settings, block->line_number,
0, 0, 0,
cx, cy, cz,
AA_end, BB_end, CC_end, u_end, v_end, w_end);
set_endpoint(cx, cy);
}
enqueue_ARC_FEED(settings, block->line_number,
find_turn(cx, cy, center_x, center_y, turn, end_x, end_y),
end_x, end_y, center_x, center_y, turn, end_z,
AA_end, BB_end, CC_end, u_end, v_end, w_end);
comp_set_current(settings, end_x, end_y, end_z);
settings->AA_current = AA_end;
settings->BB_current = BB_end;
settings->CC_current = CC_end;
settings->u_current = u_end;
settings->v_current = v_end;
settings->w_current = w_end;
return INTERP_OK;
}
int Interp::convert_arc_comp2(int move, block_pointer block, setup_pointer settings, double end_x, double end_y, double end_z, double offset_x, double offset_y,
double AA_end, double BB_end, double CC_end, double u, double v, double w) {
double alpha;
double arc_radius;
double beta;
double centerx, centery;
double delta;
double gamma;
double midx, midy;
int side;
double small = TOLERANCE_CONCAVE_CORNER;
double opx, opy, opz;
double theta;
double tool_radius;
int turn;
int plane = settings->plane;
double cx, cy, cz;
double new_end_x, new_end_y;
double spiral_abs_tolerance = (settings->length_units == CANON_UNITS_INCHES) ? settings->center_arc_radius_tolerance_inch : settings->center_arc_radius_tolerance_mm;
double radius_tolerance = (settings->length_units == CANON_UNITS_INCHES) ? RADIUS_TOLERANCE_INCH : RADIUS_TOLERANCE_MM;
comp_get_programmed(settings, &opx, &opy, &opz);
comp_get_current(settings, &cx, &cy, &cz);
if (block->r_flag) {
CHP(arc_data_r(move, plane, opx, opy, end_x, end_y,
block->r_number, block->p_flag? round_to_int(block->p_number): 1,
¢erx, ¢ery, &turn, radius_tolerance));
} else {
CHP(arc_data_ijk(move, plane,
opx, opy, end_x, end_y,
(settings->ijk_distance_mode == MODE_ABSOLUTE),
offset_x, offset_y, block->p_flag? round_to_int(block->p_number): 1,
¢erx, ¢ery, &turn, radius_tolerance, spiral_abs_tolerance, SPIRAL_RELATIVE_TOLERANCE));
}
inverse_time_rate_arc(opx, opy, opz, centerx, centery,
turn, end_x, end_y, end_z, block, settings);
side = settings->cutter_comp_side;
tool_radius = settings->cutter_comp_radius;
arc_radius = hypot((centerx - end_x), (centery - end_y));
theta = atan2(cy - opy, cx - opx);
theta = (side == LEFT) ? (theta - M_PI_2l) : (theta + M_PI_2l);
delta = atan2(centery - opy, centerx - opx);
alpha = (move == G_3) ? (delta - M_PI_2l) : (delta + M_PI_2l);
beta = (side == LEFT) ? (theta - alpha) : (alpha - theta);
beta = (beta > (1.5 * M_PIl)) ? (beta - (2 * M_PIl)) : (beta < -M_PI_2l) ? (beta + (2 * M_PIl)) : beta;
if (((side == LEFT) && (move == G_3)) || ((side == RIGHT) && (move == G_2))) {
gamma = atan2((centery - end_y), (centerx - end_x));
CHKS((arc_radius <= tool_radius),
NCE_TOOL_RADIUS_NOT_LESS_THAN_ARC_RADIUS_WITH_COMP);
} else {
gamma = atan2((end_y - centery), (end_x - centerx));
delta = (delta + M_PIl);
}
new_end_x = end_x + tool_radius * cos(gamma);
new_end_y = end_y + tool_radius * sin(gamma);
if (beta < -small ||
beta > M_PIl + small ||
(fabs(beta - M_PIl) < small && !TOOL_INSIDE_ARC(side, turn))
) {
if (qc().front().type != QARC_FEED) {
double cy = arc_radius * sin(beta - M_PI_2l);
double toward_nominal;
double dist_from_center;
double angle_from_center;
if TOOL_INSIDE_ARC(side, turn) {
dist_from_center = arc_radius - tool_radius;
toward_nominal = cy + tool_radius;
double l = toward_nominal / dist_from_center;
CHKS((l > 1.0 || l < -1.0), _("Arc move in concave corner cannot be reached by the tool without gouging"));
if(turn > 0) {
angle_from_center = theta + asin(l);
} else {
angle_from_center = theta - asin(l);
}
} else {
dist_from_center = arc_radius + tool_radius;
toward_nominal = cy - tool_radius;
double l = toward_nominal / dist_from_center;
CHKS((l > 1.0 || l < -1.0), _("Arc move in concave corner cannot be reached by the tool without gouging"));
if(turn > 0) {
angle_from_center = theta + M_PIl - asin(l);
} else {
angle_from_center = theta + M_PIl + asin(l);
}
}
midx = centerx + dist_from_center * cos(angle_from_center);
midy = centery + dist_from_center * sin(angle_from_center);
CHP(move_endpoint_and_flush(settings, midx, midy));
} else {
struct arc_feed &prev = qc().front().data.arc_feed;
double oldrad = hypot(prev.center2 - prev.end2, prev.center1 - prev.end1);
double newrad;
if TOOL_INSIDE_ARC(side, turn) {
newrad = arc_radius - tool_radius;
} else {
newrad = arc_radius + tool_radius;
}
double arc_cc, pullback, cc_dir, a;
arc_cc = hypot(prev.center2 - centery, prev.center1 - centerx);
CHKS((oldrad == 0 || arc_cc == 0), _("Arc to arc motion is invalid because the arcs have the same center"));
a = (SQ(oldrad) + SQ(arc_cc) - SQ(newrad)) / (2 * oldrad * arc_cc);
CHKS((a > 1.0 || a < -1.0), (_("Arc to arc motion makes a corner the compensated tool can't fit in without gouging")));
pullback = acos(a);
cc_dir = atan2(centery - prev.center2, centerx - prev.center1);
double dir;
if TOOL_INSIDE_ARC(side, prev.turn) {
if(turn > 0)
dir = cc_dir + pullback;
else
dir = cc_dir - pullback;
} else {
if(turn > 0)
dir = cc_dir - pullback;
else
dir = cc_dir + pullback;
}
midx = prev.center1 + oldrad * cos(dir);
midy = prev.center2 + oldrad * sin(dir);
CHP(move_endpoint_and_flush(settings, midx, midy));
}
enqueue_ARC_FEED(settings, block->line_number,
find_turn(opx, opy, centerx, centery, turn, end_x, end_y),
new_end_x, new_end_y, centerx, centery, turn, end_z,
AA_end, BB_end, CC_end, u, v, w);
} else if (beta > small) {
midx = opx + tool_radius * cos(delta);
midy = opy + tool_radius * sin(delta);
dequeue_canons(settings);
enqueue_ARC_FEED(settings, block->line_number,
0.0, midx, midy, opx, opy, ((side == LEFT) ? -1 : 1),
cz,
AA_end, BB_end, CC_end, u, v, w);
dequeue_canons(settings);
set_endpoint(midx, midy);
enqueue_ARC_FEED(settings, block->line_number,
find_turn(opx, opy, centerx, centery, turn, end_x, end_y),
new_end_x, new_end_y, centerx, centery, turn, end_z,
AA_end, BB_end, CC_end, u, v, w);
} else {
dequeue_canons(settings);
set_endpoint(cx, cy);
enqueue_ARC_FEED(settings, block->line_number,
find_turn(opx, opy, centerx, centery, turn, end_x, end_y),
new_end_x, new_end_y, centerx, centery, turn, end_z,
AA_end, BB_end, CC_end, u, v, w);
}
comp_set_programmed(settings, end_x, end_y, end_z);
comp_set_current(settings, new_end_x, new_end_y, end_z);
settings->AA_current = AA_end;
settings->BB_current = BB_end;
settings->CC_current = CC_end;
settings->u_current = u;
settings->v_current = v;
settings->w_current = w;
return INTERP_OK;
}
int Interp::convert_axis_offsets(int g_code, block_pointer block, setup_pointer settings) {
double *pars;
CHKS((settings->cutter_comp_side),
NCE_CANNOT_CHANGE_AXIS_OFFSETS_WITH_CUTTER_RADIUS_COMP);
CHKS((block->a_flag && settings->a_axis_wrapped &&
(block->a_number <= -360.0 || block->a_number >= 360.0)),
(_("Invalid absolute position %5.2f for wrapped rotary axis %c")),
block->a_number, 'A');
CHKS((block->b_flag && settings->b_axis_wrapped &&
(block->b_number <= -360.0 || block->b_number >= 360.0)),
(_("Invalid absolute position %5.2f for wrapped rotary axis %c")),
block->b_number, 'B');
CHKS((block->c_flag && settings->c_axis_wrapped &&
(block->c_number <= -360.0 || block->c_number >= 360.0)),
(_("Invalid absolute position %5.2f for wrapped rotary axis %c")),
block->c_number, 'C');
pars = settings->parameters;
if ((g_code == G_52) || (g_code == G_92)) {
pars[G92_APPLIED] = 1.0;
if (g_code == G_52) {
if (block->x_flag) {
settings->current_x += settings->axis_offset_x - block->x_number;
settings->axis_offset_x = block->x_number;
}
if (block->y_flag) {
settings->current_y += settings->axis_offset_y - block->y_number;
settings->axis_offset_y = block->y_number;
}
if (block->z_flag) {
settings->current_z += settings->axis_offset_z - block->z_number;
settings->axis_offset_z = block->z_number;
}
if (block->a_flag) {
settings->AA_current += settings->AA_axis_offset - block->a_number;
settings->AA_axis_offset = block->a_number;
}
if (block->b_flag) {
settings->BB_current += settings->BB_axis_offset - block->b_number;
settings->BB_axis_offset = block->b_number;
}
if (block->c_flag) {
settings->CC_current += settings->CC_axis_offset - block->c_number;
settings->CC_axis_offset = block->c_number;
}
if (block->u_flag) {
settings->u_current += settings->u_axis_offset - block->u_number;
settings->u_axis_offset = block->u_number;
}
if (block->v_flag) {
settings->v_current += settings->v_axis_offset - block->v_number;
settings->v_axis_offset = block->v_number;
}
if (block->w_flag) {
settings->w_current += settings->w_axis_offset - block->w_number;
settings->w_axis_offset = block->w_number;
}
} else {
if (block->x_flag) {
settings->axis_offset_x =
(settings->current_x + settings->axis_offset_x - block->x_number);
settings->current_x = block->x_number;
}
if (block->y_flag) {
settings->axis_offset_y =
(settings->current_y + settings->axis_offset_y - block->y_number);
settings->current_y = block->y_number;
}
if (block->z_flag) {
settings->axis_offset_z =
(settings->current_z + settings->axis_offset_z - block->z_number);
settings->current_z = block->z_number;
}
if (block->a_flag) {
settings->AA_axis_offset = (settings->AA_current +
settings->AA_axis_offset - block->a_number);
settings->AA_current = block->a_number;
}
if (block->b_flag) {
settings->BB_axis_offset = (settings->BB_current +
settings->BB_axis_offset - block->b_number);
settings->BB_current = block->b_number;
}
if (block->c_flag) {
settings->CC_axis_offset = (settings->CC_current +
settings->CC_axis_offset - block->c_number);
settings->CC_current = block->c_number;
}
if (block->u_flag) {
settings->u_axis_offset = (settings->u_current +
settings->u_axis_offset - block->u_number);
settings->u_current = block->u_number;
}
if (block->v_flag) {
settings->v_axis_offset = (settings->v_current +
settings->v_axis_offset - block->v_number);
settings->v_current = block->v_number;
}
if (block->w_flag) {
settings->w_axis_offset = (settings->w_current +
settings->w_axis_offset - block->w_number);
settings->w_current = block->w_number;
}
}
SET_G92_OFFSET(settings->axis_offset_x,
settings->axis_offset_y,
settings->axis_offset_z,
settings->AA_axis_offset,
settings->BB_axis_offset,
settings->CC_axis_offset,
settings->u_axis_offset,
settings->v_axis_offset,
settings->w_axis_offset);
pars[5211] = PROGRAM_TO_USER_LEN(settings->axis_offset_x);
pars[5212] = PROGRAM_TO_USER_LEN(settings->axis_offset_y);
pars[5213] = PROGRAM_TO_USER_LEN(settings->axis_offset_z);
pars[5214] = PROGRAM_TO_USER_ANG(settings->AA_axis_offset);
pars[5215] = PROGRAM_TO_USER_ANG(settings->BB_axis_offset);
pars[5216] = PROGRAM_TO_USER_ANG(settings->CC_axis_offset);
pars[5217] = PROGRAM_TO_USER_LEN(settings->u_axis_offset);
pars[5218] = PROGRAM_TO_USER_LEN(settings->v_axis_offset);
pars[5219] = PROGRAM_TO_USER_LEN(settings->w_axis_offset);
} else if ((g_code == G_92_1) || (g_code == G_92_2)) {
pars[5210] = 0.0;
settings->current_x = settings->current_x + settings->axis_offset_x;
settings->current_y = settings->current_y + settings->axis_offset_y;
settings->current_z = settings->current_z + settings->axis_offset_z;
settings->AA_current = (settings->AA_current + settings->AA_axis_offset);
settings->BB_current = (settings->BB_current + settings->BB_axis_offset);
settings->CC_current = (settings->CC_current + settings->CC_axis_offset);
settings->u_current = (settings->u_current + settings->u_axis_offset);
settings->v_current = (settings->v_current + settings->v_axis_offset);
settings->w_current = (settings->w_current + settings->w_axis_offset);
SET_G92_OFFSET(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
settings->axis_offset_x = 0.0;
settings->axis_offset_y = 0.0;
settings->axis_offset_z = 0.0;
settings->AA_axis_offset = 0.0;
settings->BB_axis_offset = 0.0;
settings->CC_axis_offset = 0.0;
settings->u_axis_offset = 0.0;
settings->v_axis_offset = 0.0;
settings->w_axis_offset = 0.0;
if (g_code == G_92_1) {
pars[G92_X] = 0.0;
pars[G92_Y] = 0.0;
pars[G92_Z] = 0.0;
pars[G92_A] = 0.0;
pars[G92_B] = 0.0;
pars[G92_C] = 0.0;
pars[G92_U] = 0.0;
pars[G92_V] = 0.0;
pars[G92_W] = 0.0;
}
} else if (g_code == G_92_3) {
pars[5210] = 1.0;
settings->current_x =
settings->current_x + settings->axis_offset_x - USER_TO_PROGRAM_LEN(pars[5211]);
settings->current_y =
settings->current_y + settings->axis_offset_y - USER_TO_PROGRAM_LEN(pars[5212]);
settings->current_z =
settings->current_z + settings->axis_offset_z - USER_TO_PROGRAM_LEN(pars[5213]);
settings->AA_current =
settings->AA_current + settings->AA_axis_offset - USER_TO_PROGRAM_ANG(pars[5214]);
settings->BB_current =
settings->BB_current + settings->BB_axis_offset - USER_TO_PROGRAM_ANG(pars[5215]);
settings->CC_current =
settings->CC_current + settings->CC_axis_offset - USER_TO_PROGRAM_ANG(pars[5216]);
settings->u_current =
settings->u_current + settings->u_axis_offset - USER_TO_PROGRAM_LEN(pars[5217]);
settings->v_current =
settings->v_current + settings->v_axis_offset - USER_TO_PROGRAM_LEN(pars[5218]);
settings->w_current =
settings->w_current + settings->w_axis_offset - USER_TO_PROGRAM_LEN(pars[5219]);
settings->axis_offset_x = USER_TO_PROGRAM_LEN(pars[5211]);
settings->axis_offset_y = USER_TO_PROGRAM_LEN(pars[5212]);
settings->axis_offset_z = USER_TO_PROGRAM_LEN(pars[5213]);
settings->AA_axis_offset = USER_TO_PROGRAM_ANG(pars[5214]);
settings->BB_axis_offset = USER_TO_PROGRAM_ANG(pars[5215]);
settings->CC_axis_offset = USER_TO_PROGRAM_ANG(pars[5216]);
settings->u_axis_offset = USER_TO_PROGRAM_LEN(pars[5217]);
settings->v_axis_offset = USER_TO_PROGRAM_LEN(pars[5218]);
settings->w_axis_offset = USER_TO_PROGRAM_LEN(pars[5219]);
SET_G92_OFFSET(settings->axis_offset_x,
settings->axis_offset_y,
settings->axis_offset_z,
settings->AA_axis_offset,
settings->BB_axis_offset,
settings->CC_axis_offset,
settings->u_axis_offset,
settings->v_axis_offset,
settings->w_axis_offset);
} else
ERS(NCE_BUG_CODE_NOT_IN_G52_G92_SERIES);
return INTERP_OK;
}
#define VAL_LEN 30
int Interp::convert_param_comment(char *comment, char *expanded, int len)
{
int i;
char param[LINELEN+1];
int paramNumber;
int stat;
double value;
char valbuf[VAL_LEN]; char *v;
int found;
while(*comment)
{
if(*comment == '#')
{
found = 0;
logDebug("a parameter");
comment++;
CHKS((0 == *comment), NCE_NAMED_PARAMETER_NOT_TERMINATED);
if(isdigit(*comment)) {
logDebug("numeric parameter");
for(i=0; isdigit(*comment)&& (i<LINELEN); i++)
{
param[i] = *comment++;
}
param[i] = 0;
paramNumber = atoi(param);
if((paramNumber >= 0) &&
(paramNumber < RS274NGC_MAX_PARAMETERS))
{
value = _setup.parameters[paramNumber];
found = 1;
}
}
else if(*comment == '<')
{
logDebug("name parameter");
comment++;
CHKS((0 == *comment), NCE_NAMED_PARAMETER_NOT_TERMINATED);
for(i=0; (')' != *comment) &&
(i<LINELEN) && (0 != *comment);)
{
if('>' == *comment)
{
break; }
if(isspace(*comment)) {
comment++;
continue;
}
else
{
int c = *comment++;
if (FEATURE(NO_DOWNCASE_OWORD))
param[i] = c;
else
param[i] = tolower(c);
i++;
}
}
if('>' != *comment)
{
ERS(NCE_NAMED_PARAMETER_NOT_TERMINATED);
}
else
{
comment++;
}
param[i] = 0;
find_named_param(param, &stat, &value);
if(stat)
{
found = 1;
}
}
else
{
logDebug("neither numeric nor name");
*expanded++ = '#';
CHKS((*comment == 0), NCE_NAMED_PARAMETER_NOT_TERMINATED);
continue;
}
if(found)
{
double pvalue = equal(value, 0.0) ? 0.0 : value;
int n = snprintf(valbuf, VAL_LEN, "%lf", pvalue);
bool fail = (n >= VAL_LEN || n < 0);
if(fail)
strcpy(valbuf, "######");
}
else
{
strcpy(valbuf, "######");
}
logDebug("found:%d value:|%s|", found, valbuf);
v = valbuf;
while(*v)
{
*expanded++ = *v++;
}
}
else {
*expanded++ = *comment++;
}
}
*expanded = 0;
return INTERP_OK;
}
static int streq(char *s1, char *s2) {
return !strcmp(s1, s2);
}
static int startswith(char *haystack, char *needle) {
return !strncmp(haystack, needle, strlen(needle));
}
int Interp::convert_comment(char *comment, bool enqueue) {
enum
{ LC_SIZE = 256, EX_SIZE = 2*LC_SIZE}; char lc[LC_SIZE+1];
char expanded[EX_SIZE+1];
char MSG_STR[] = "msg,";
char DEBUG_STR[] = "debug,";
char PRINT_STR[] = "print,";
char LOG_STR[] = "log,";
char LOGOPEN_STR[] = "logopen,";
char LOGAPPEND_STR[] = "logappend,";
char LOGCLOSE_STR[] = "logclose";
char PY_STR[] = "py,";
char PYRUN_STR[] = "pyrun,";
char PYRELOAD_STR[] = "pyreload";
char ABORT_STR[] = "abort,";
int m, n, start;
m = 0;
while (isspace(comment[m]))
m++;
start = m;
for (n = 0; n < LC_SIZE && comment[m] != 0; m++, n++) {
lc[n] = tolower(comment[m]);
}
lc[n] = 0;
if (startswith(lc, MSG_STR)) {
MESSAGE(comment + start + strlen(MSG_STR));
return INTERP_OK;
}
else if (startswith(lc, DEBUG_STR))
{
convert_param_comment(comment+start+strlen(DEBUG_STR), expanded,
EX_SIZE);
if (_setup.parameters[5599] > 0.0)
MESSAGE(expanded);
return INTERP_OK;
}
else if (startswith(lc, PRINT_STR))
{
convert_param_comment(comment+start+strlen(PRINT_STR), expanded,
EX_SIZE);
fprintf(stdout, "%s\n", expanded);
fflush(stdout);
return INTERP_OK;
}
else if (startswith(lc, LOG_STR))
{
convert_param_comment(comment+start+strlen(LOG_STR), expanded,
EX_SIZE);
LOG(expanded);
return INTERP_OK;
}
else if (startswith(lc, LOGOPEN_STR))
{
LOGOPEN(comment + start + strlen(LOGOPEN_STR));
return INTERP_OK;
}
else if (startswith(lc, LOGAPPEND_STR))
{
LOGAPPEND(comment + start + strlen(LOGAPPEND_STR));
return INTERP_OK;
}
else if (startswith(lc, PY_STR))
{
return py_execute(comment + start + strlen(PY_STR), false);
}
else if (startswith(lc, PYRUN_STR))
{
return py_execute(comment + start + strlen(PYRUN_STR), true);
}
else if (startswith(lc, PYRELOAD_STR))
{
return py_reload();
}
else if (startswith(lc, ABORT_STR))
{
convert_param_comment(comment+start+strlen(ABORT_STR), expanded,
EX_SIZE);
setSavedError(expanded); return INTERP_ERROR;
}
else if (streq(lc, LOGCLOSE_STR))
{
LOGCLOSE();
return INTERP_OK;
}
if (enqueue)
enqueue_COMMENT(comment + start);
return INTERP_OK;
}
int Interp::convert_control_mode(int g_code, double tolerance, double naivecam_tolerance, setup_pointer settings) {
CHKS((settings->cutter_comp_side),
(_("Cannot change control mode with cutter radius compensation on")));
if (g_code == G_61) {
SET_MOTION_CONTROL_MODE(CANON_EXACT_PATH, 0);
settings->control_mode = CANON_EXACT_PATH;
} else if (g_code == G_61_1) {
SET_MOTION_CONTROL_MODE(CANON_EXACT_STOP, 0);
settings->control_mode = CANON_EXACT_STOP;
} else if (g_code == G_64) {
if (tolerance >= 0) {
SET_MOTION_CONTROL_MODE(CANON_CONTINUOUS, tolerance);
} else {
SET_MOTION_CONTROL_MODE(CANON_CONTINUOUS, 0);
}
if (naivecam_tolerance >= 0) {
SET_NAIVECAM_TOLERANCE(naivecam_tolerance);
} else if (tolerance >= 0) {
SET_NAIVECAM_TOLERANCE(tolerance); } else {
SET_NAIVECAM_TOLERANCE(0);
}
settings->control_mode = CANON_CONTINUOUS;
} else
ERS(NCE_BUG_CODE_NOT_G61_G61_1_OR_G64);
return INTERP_OK;
}
void Interp::rotate(double *x, double *y, double theta) {
double xx, yy;
double t = D2R(theta);
xx = *x * cos(t) - *y * sin(t);
yy = *x * sin(t) + *y * cos(t);
*x = xx;
*y = yy;
}
int Interp::convert_coordinate_system(int g_code, setup_pointer settings) {
int origin;
double *parameters;
CHKS((settings->cutter_comp_side),
(_("Cannot change coordinate systems with cutter radius compensation on")));
parameters = settings->parameters;
switch (g_code) {
case G_54:
origin = 1;
break;
case G_55:
origin = 2;
break;
case G_56:
origin = 3;
break;
case G_57:
origin = 4;
break;
case G_58:
origin = 5;
break;
case G_59:
origin = 6;
break;
case G_59_1:
origin = 7;
break;
case G_59_2:
origin = 8;
break;
case G_59_3:
origin = 9;
break;
default:
ERS(NCE_BUG_CODE_NOT_IN_RANGE_G54_TO_G593);
}
if (origin == settings->origin_index) {
#ifdef DEBUG_EMC
enqueue_COMMENT("interpreter: continuing to use same coordinate system");
#endif
return INTERP_OK;
}
find_current_in_system(settings, origin,
&settings->current_x, &settings->current_y, &settings->current_z,
&settings->AA_current, &settings->BB_current, &settings->CC_current,
&settings->u_current, &settings->v_current, &settings->w_current);
settings->origin_index = origin;
parameters[5220] = (double) origin;
settings->origin_offset_x = USER_TO_PROGRAM_LEN(parameters[5201 + (origin * 20)]);
settings->origin_offset_y = USER_TO_PROGRAM_LEN(parameters[5202 + (origin * 20)]);
settings->origin_offset_z = USER_TO_PROGRAM_LEN(parameters[5203 + (origin * 20)]);
settings->AA_origin_offset = USER_TO_PROGRAM_ANG(parameters[5204 + (origin * 20)]);
settings->BB_origin_offset = USER_TO_PROGRAM_ANG(parameters[5205 + (origin * 20)]);
settings->CC_origin_offset = USER_TO_PROGRAM_ANG(parameters[5206 + (origin * 20)]);
settings->u_origin_offset = USER_TO_PROGRAM_LEN(parameters[5207 + (origin * 20)]);
settings->v_origin_offset = USER_TO_PROGRAM_LEN(parameters[5208 + (origin * 20)]);
settings->w_origin_offset = USER_TO_PROGRAM_LEN(parameters[5209 + (origin * 20)]);
settings->rotation_xy = parameters[5210 + (origin * 20)];
SET_G5X_OFFSET(origin,
settings->origin_offset_x,
settings->origin_offset_y,
settings->origin_offset_z,
settings->AA_origin_offset,
settings->BB_origin_offset,
settings->CC_origin_offset,
settings->u_origin_offset,
settings->v_origin_offset,
settings->w_origin_offset);
SET_G92_OFFSET(settings->axis_offset_x,
settings->axis_offset_y,
settings->axis_offset_z,
settings->AA_axis_offset,
settings->BB_axis_offset,
settings->CC_axis_offset,
settings->u_axis_offset,
settings->v_axis_offset,
settings->w_axis_offset);
SET_XY_ROTATION(settings->rotation_xy);
return INTERP_OK;
}
int Interp::convert_cutter_compensation(int g_code, block_pointer block, setup_pointer settings) {
if (g_code == G_40) {
CHP(convert_cutter_compensation_off(settings));
} else if (g_code == G_41) {
CHP(convert_cutter_compensation_on(LEFT, block, settings));
} else if (g_code == G_42) {
CHP(convert_cutter_compensation_on(RIGHT, block, settings));
} else if (g_code == G_41_1) {
CHP(convert_cutter_compensation_on(LEFT, block, settings));
} else if (g_code == G_42_1) {
CHP(convert_cutter_compensation_on(RIGHT, block, settings));
} else
ERS("BUG: Code not G40, G41, G41.1, G42, G42.1");
return INTERP_OK;
}
int Interp::convert_cutter_compensation_off(setup_pointer settings) {
#ifdef DEBUG_EMC
enqueue_COMMENT("interpreter: cutter radius compensation off");
#endif
if(settings->cutter_comp_side && settings->cutter_comp_radius > 0.0 &&
!settings->cutter_comp_firstmove) {
double cx, cy, cz;
comp_get_current(settings, &cx, &cy, &cz);
CHP(move_endpoint_and_flush(settings, cx, cy));
dequeue_canons(settings);
settings->current_x = settings->program_x;
settings->current_y = settings->program_y;
settings->current_z = settings->program_z;
settings->arc_not_allowed = true;
}
settings->cutter_comp_side = false;
settings->cutter_comp_firstmove = true;
return INTERP_OK;
}
static int is_near_int(int *result, double value) {
*result = (int)(value + .5);
return fabs(*result - value) < .0001;
}
int Interp::convert_cutter_compensation_on(int side, block_pointer block, setup_pointer settings) {
double radius;
int pocket_number, orientation;
CHKS((settings->plane != CANON_PLANE_XY && settings->plane != CANON_PLANE_XZ),
NCE_RADIUS_COMP_ONLY_IN_XY_OR_XZ);
CHKS((settings->cutter_comp_side),
NCE_CANNOT_TURN_CUTTER_RADIUS_COMP_ON_WHEN_ON);
if(block->g_modes[GM_CUTTER_COMP] == G_41_1 || block->g_modes[GM_CUTTER_COMP] == G_42_1) {
CHKS((!block->d_flag),
_("G%d.1 with no D word"), block->g_modes[GM_CUTTER_COMP]/10 );
radius = block->d_number_float / 2;
if(block->l_number != -1) {
CHKS((settings->plane != CANON_PLANE_XZ), _("G%d.1 with L word, but plane is not G18"), block->g_modes[GM_CUTTER_COMP]/10);
orientation = block->l_number;
} else {
orientation = 0;
}
} else {
if(!block->d_flag) {
pocket_number = 0;
} else {
int tool;
CHKS(!is_near_int(&tool, block->d_number_float),
_("G%d requires D word to be a whole number"),
block->g_modes[GM_CUTTER_COMP]/10);
CHKS((tool < 0), NCE_NEGATIVE_D_WORD_TOOL_RADIUS_INDEX_USED);
CHP((find_tool_pocket(settings, tool, &pocket_number)));
}
radius = USER_TO_PROGRAM_LEN(settings->tool_table[pocket_number].diameter) / 2.0;
orientation = settings->tool_table[pocket_number].orientation;
CHKS((settings->plane != CANON_PLANE_XZ && orientation != 0 && orientation != 9), _("G%d with lathe tool, but plane is not G18"), block->g_modes[7]/10);
}
if (radius < 0.0) {
radius = -radius;
if (side == RIGHT)
side = LEFT;
else
side = RIGHT;
}
#ifdef DEBUG_EMC
if (side == RIGHT)
enqueue_COMMENT("interpreter: cutter radius compensation on right");
else
enqueue_COMMENT("interpreter: cutter radius compensation on left");
#endif
settings->cutter_comp_radius = radius;
settings->cutter_comp_orientation = orientation;
settings->cutter_comp_side = side;
return INTERP_OK;
}
int Interp::convert_distance_mode(int g_code, setup_pointer settings) {
if (g_code == G_90) {
if (settings->distance_mode != MODE_ABSOLUTE) {
#ifdef DEBUG_EMC
enqueue_COMMENT("interpreter: distance mode changed to absolute");
#endif
settings->distance_mode = MODE_ABSOLUTE;
}
} else if (g_code == G_91) {
if (settings->distance_mode != MODE_INCREMENTAL) {
#ifdef DEBUG_EMC
enqueue_COMMENT("interpreter: distance mode changed to incremental");
#endif
settings->distance_mode = MODE_INCREMENTAL;
}
} else
ERS(NCE_BUG_CODE_NOT_G90_OR_G91);
return INTERP_OK;
}
int Interp::convert_ijk_distance_mode(int g_code, setup_pointer settings) {
if (g_code == G_90_1) {
if (settings->ijk_distance_mode != MODE_ABSOLUTE) {
#ifdef DEBUG_EMC
enqueue_COMMENT("interpreter: IJK distance mode changed to absolute");
#endif
settings->ijk_distance_mode = MODE_ABSOLUTE;
}
} else if (g_code == G_91_1) {
if (settings->ijk_distance_mode != MODE_INCREMENTAL) {
#ifdef DEBUG_EMC
enqueue_COMMENT("interpreter: IJK distance mode changed to incremental");
#endif
settings->ijk_distance_mode = MODE_INCREMENTAL;
}
} else
ERS(NCE_BUG_CODE_NOT_G90_OR_G91);
return INTERP_OK;
}
int Interp::convert_lathe_diameter_mode(int g_code, block_pointer block, setup_pointer settings) {
if (g_code == G_7) {
if (!settings->lathe_diameter_mode) {
if(block->x_flag)
{
block->x_number /= 2; }
if(block->motion_to_be == G_76) {
block->i_number /= 2;
block->j_number /= 2;
block->k_number /= 2;
}
#ifdef DEBUG_EMC
COMMENT("interpreter: Lathe diameter mode changed to diameter");
#endif
settings->lathe_diameter_mode = true;
}
} else if (g_code == G_8) {
if (settings->lathe_diameter_mode) {
if(block->x_flag)
{
block->x_number *= 2; }
if(block->motion_to_be == G_76) {
block->i_number *= 2;
block->j_number *= 2;
block->k_number *= 2;
}
#ifdef DEBUG_EMC
COMMENT("interpreter: Lathe diameter mode changed to radius");
#endif
settings->lathe_diameter_mode = false;
}
} else
ERS("BUG: Code not G7 or G8");
return INTERP_OK;
}
int Interp::convert_dwell(setup_pointer settings, double time) {
enqueue_DWELL(time);
return INTERP_OK;
}
int Interp::convert_feed_mode(int g_code, setup_pointer settings) {
if (g_code == G_93) {
#ifdef DEBUG_EMC
enqueue_COMMENT("interpreter: feed mode set to inverse time");
#endif
settings->feed_mode = INVERSE_TIME;
enqueue_SET_FEED_MODE(0, 0);
} else if (g_code == G_94) {
#ifdef DEBUG_EMC
enqueue_COMMENT("interpreter: feed mode set to units per minute");
#endif
settings->feed_mode = UNITS_PER_MINUTE;
enqueue_SET_FEED_MODE(0, 0);
settings->feed_rate = 0.0;
enqueue_SET_FEED_RATE(0);
} else if(g_code == G_95) {
#ifdef DEBUG_EMC
enqueue_COMMENT("interpreter: feed mode set to units per revolution");
#endif
settings->feed_mode = UNITS_PER_REVOLUTION;
enqueue_SET_FEED_MODE(settings->active_spindle , 1);
settings->feed_rate = 0.0;
enqueue_SET_FEED_RATE(0);
} else
ERS("BUG: Code not G93, G94, or G95");
return INTERP_OK;
}
int Interp::convert_feed_rate(block_pointer block, setup_pointer settings) {
settings->feed_rate = block->f_number;
enqueue_SET_FEED_RATE(block->f_number);
return INTERP_OK;
}
int Interp::convert_g(block_pointer block, setup_pointer settings) {
int status;
if ((block->g_modes[GM_MODAL_0] == G_4) && ONCE(STEP_DWELL)) {
status = convert_dwell(settings, block->p_number);
CHP(status);
}
if ((block->g_modes[GM_SET_PLANE] != -1) && ONCE(STEP_SET_PLANE)) {
status = convert_set_plane(block->g_modes[GM_SET_PLANE], settings);
CHP(status);
}
if ((block->g_modes[GM_LENGTH_UNITS] != -1) && ONCE(STEP_LENGTH_UNITS)) {
status = convert_length_units(block->g_modes[GM_LENGTH_UNITS], settings);
CHP(status);
}
if ((block->g_modes[GM_LATHE_DIAMETER_MODE] != -1) && ONCE(STEP_LATHE_DIAMETER_MODE)) {
status = convert_lathe_diameter_mode(block->g_modes[GM_LATHE_DIAMETER_MODE], block, settings);
CHP(status);
}
if ((block->g_modes[GM_CUTTER_COMP] != -1) && ONCE(STEP_CUTTER_COMP)) {
status = convert_cutter_compensation(block->g_modes[GM_CUTTER_COMP], block, settings);
CHP(status);
}
if ((block->g_modes[GM_TOOL_LENGTH_OFFSET] != -1) && ONCE(STEP_TOOL_LENGTH_OFFSET)){
status = convert_tool_length_offset(block->g_modes[GM_TOOL_LENGTH_OFFSET], block, settings);
CHP(status);
}
if ((block->g_modes[GM_COORD_SYSTEM] != -1) && ONCE(STEP_COORD_SYSTEM)){
status = convert_coordinate_system(block->g_modes[GM_COORD_SYSTEM], settings);
CHP(status);
}
if ((block->g_modes[GM_CONTROL_MODE] != -1) && ONCE(STEP_CONTROL_MODE)) {
status = convert_control_mode(block->g_modes[GM_CONTROL_MODE],
block->p_number, block->q_number, settings);
CHP(status);
}
if ((block->g_modes[GM_DISTANCE_MODE] != -1) && ONCE(STEP_DISTANCE_MODE)) {
status = convert_distance_mode(block->g_modes[GM_DISTANCE_MODE], settings);
CHP(status);
}
if ((block->g_modes[GM_IJK_DISTANCE_MODE] != -1) && ONCE(STEP_IJK_DISTANCE_MODE)){
status = convert_ijk_distance_mode(block->g_modes[GM_IJK_DISTANCE_MODE], settings);
CHP(status);
}
if ((block->g_modes[GM_RETRACT_MODE] != -1) && ONCE(STEP_RETRACT_MODE)){
status = convert_retract_mode(block->g_modes[GM_RETRACT_MODE], settings);
CHP(status);
}
if ((block->g_modes[GM_MODAL_0] != -1) && ONCE(STEP_MODAL_0)) {
status = convert_modal_0(block->g_modes[GM_MODAL_0], block, settings);
CHP(status);
}
if ((block->motion_to_be != -1) && ONCE(STEP_MOTION)){
status = convert_motion(block->motion_to_be, block, settings);
CHP(status);
}
return INTERP_OK;
}
int Interp::convert_savehome(int code, block_pointer block, setup_pointer s) {
double *p = s->parameters;
if(s->cutter_comp_side) {
ERS(_("Cannot set reference point with cutter compensation in effect"));
}
double x = PROGRAM_TO_USER_LEN(s->current_x + s->tool_offset.tran.x + s->origin_offset_x + s->axis_offset_x);
double y = PROGRAM_TO_USER_LEN(s->current_y + s->tool_offset.tran.y + s->origin_offset_y + s->axis_offset_y);
double z = PROGRAM_TO_USER_LEN(s->current_z + s->tool_offset.tran.z + s->origin_offset_z + s->axis_offset_z);
double a = PROGRAM_TO_USER_ANG(s->AA_current + s->tool_offset.a + s->AA_origin_offset + s->AA_axis_offset);
double b = PROGRAM_TO_USER_ANG(s->BB_current + s->tool_offset.b + s->BB_origin_offset + s->BB_axis_offset);
double c = PROGRAM_TO_USER_ANG(s->CC_current + s->tool_offset.c + s->CC_origin_offset + s->CC_axis_offset);
double u = PROGRAM_TO_USER_LEN(s->u_current + s->tool_offset.u + s->u_origin_offset + s->u_axis_offset);
double v = PROGRAM_TO_USER_LEN(s->v_current + s->tool_offset.v + s->v_origin_offset + s->v_axis_offset);
double w = PROGRAM_TO_USER_LEN(s->w_current + s->tool_offset.w + s->w_origin_offset + s->w_axis_offset);
if(s->a_axis_wrapped) {
a = fmod(a, 360.0);
if(a<0) a += 360.0;
}
if(s->b_axis_wrapped) {
b = fmod(b, 360.0);
if(b<0) b += 360.0;
}
if(s->c_axis_wrapped) {
c = fmod(c, 360.0);
if(c<0) c += 360.0;
}
if(code == G_28_1) {
p[5161] = x;
p[5162] = y;
p[5163] = z;
p[5164] = a;
p[5165] = b;
p[5166] = c;
p[5167] = u;
p[5168] = v;
p[5169] = w;
} else if(code == G_30_1) {
p[5181] = x;
p[5182] = y;
p[5183] = z;
p[5184] = a;
p[5185] = b;
p[5186] = c;
p[5187] = u;
p[5188] = v;
p[5189] = w;
} else {
ERS("BUG: Code not G28.1 or G38.1");
}
return INTERP_OK;
}
int Interp::convert_home(int move, block_pointer block, setup_pointer settings) {
double end_x;
double end_y;
double end_z;
double AA_end;
double BB_end;
double CC_end;
double u_end;
double v_end;
double w_end;
double end_x_home;
double end_y_home;
double end_z_home;
double AA_end_home;
double BB_end_home;
double CC_end_home;
double u_end_home;
double v_end_home;
double w_end_home;
double *parameters;
parameters = settings->parameters;
CHP(find_ends(block, settings, &end_x, &end_y, &end_z,
&AA_end, &BB_end, &CC_end,
&u_end, &v_end, &w_end));
CHKS((settings->cutter_comp_side),
NCE_CANNOT_USE_G28_OR_G30_WITH_CUTTER_RADIUS_COMP);
if (AA_end != settings->AA_current && (-1 != settings->a_indexer_jnum) )
issue_straight_index(3,settings->a_indexer_jnum, AA_end, block->line_number, settings);
if (BB_end != settings->BB_current && (-1 != settings->b_indexer_jnum) )
issue_straight_index(4,settings->b_indexer_jnum, BB_end, block->line_number, settings);
if (CC_end != settings->CC_current && (-1 != settings->c_indexer_jnum) )
issue_straight_index(5,settings->c_indexer_jnum, CC_end, block->line_number, settings);
STRAIGHT_TRAVERSE(block->line_number, end_x, end_y, end_z,
AA_end, BB_end, CC_end,
u_end, v_end, w_end);
settings->current_x = end_x;
settings->current_y = end_y;
settings->current_z = end_z;
settings->AA_current = AA_end;
settings->BB_current = BB_end;
settings->CC_current = CC_end;
settings->u_current = u_end;
settings->v_current = v_end;
settings->w_current = w_end;
if (move == G_28) {
find_relative(USER_TO_PROGRAM_LEN(parameters[5161]),
USER_TO_PROGRAM_LEN(parameters[5162]),
USER_TO_PROGRAM_LEN(parameters[5163]),
USER_TO_PROGRAM_ANG(parameters[5164]),
USER_TO_PROGRAM_ANG(parameters[5165]),
USER_TO_PROGRAM_ANG(parameters[5166]),
USER_TO_PROGRAM_LEN(parameters[5167]),
USER_TO_PROGRAM_LEN(parameters[5168]),
USER_TO_PROGRAM_LEN(parameters[5169]),
&end_x_home, &end_y_home, &end_z_home,
&AA_end_home, &BB_end_home, &CC_end_home,
&u_end_home, &v_end_home, &w_end_home, settings);
} else if (move == G_30) {
find_relative(USER_TO_PROGRAM_LEN(parameters[5181]),
USER_TO_PROGRAM_LEN(parameters[5182]),
USER_TO_PROGRAM_LEN(parameters[5183]),
USER_TO_PROGRAM_ANG(parameters[5184]),
USER_TO_PROGRAM_ANG(parameters[5185]),
USER_TO_PROGRAM_ANG(parameters[5186]),
USER_TO_PROGRAM_LEN(parameters[5187]),
USER_TO_PROGRAM_LEN(parameters[5188]),
USER_TO_PROGRAM_LEN(parameters[5189]),
&end_x_home, &end_y_home, &end_z_home,
&AA_end_home, &BB_end_home, &CC_end_home,
&u_end_home, &v_end_home, &w_end_home, settings);
} else
ERS(NCE_BUG_CODE_NOT_G28_OR_G30);
if (block->x_flag) end_x = end_x_home;
if (block->y_flag) end_y = end_y_home;
if (block->z_flag) end_z = end_z_home;
if (block->a_flag) AA_end = AA_end_home;
if (block->b_flag) BB_end = BB_end_home;
if (block->c_flag) CC_end = CC_end_home;
if (block->u_flag) u_end = u_end_home;
if (block->v_flag) v_end = v_end_home;
if (block->w_flag) w_end = w_end_home;
if (!block->x_flag && !block->y_flag && !block->z_flag &&
!block->a_flag && !block->b_flag && !block->c_flag &&
!block->u_flag && !block->v_flag && !block->w_flag) {
end_x = end_x_home;
end_y = end_y_home;
end_z = end_z_home;
AA_end = AA_end_home;
BB_end = BB_end_home;
CC_end = CC_end_home;
u_end = u_end_home;
v_end = v_end_home;
w_end = w_end_home;
}
if (AA_end != settings->AA_current && (-1 != settings->a_indexer_jnum) )
issue_straight_index(3,settings->a_indexer_jnum, AA_end, block->line_number, settings);
if (BB_end != settings->BB_current && (-1 != settings->b_indexer_jnum) )
issue_straight_index(4,settings->b_indexer_jnum, BB_end, block->line_number, settings);
if (CC_end != settings->CC_current && (-1 != settings->c_indexer_jnum) )
issue_straight_index(5,settings->c_indexer_jnum, CC_end, block->line_number, settings);
STRAIGHT_TRAVERSE(block->line_number, end_x, end_y, end_z,
AA_end, BB_end, CC_end,
u_end, v_end, w_end);
settings->current_x = end_x;
settings->current_y = end_y;
settings->current_z = end_z;
settings->AA_current = AA_end;
settings->BB_current = BB_end;
settings->CC_current = CC_end;
settings->u_current = u_end;
settings->v_current = v_end;
settings->w_current = w_end;
return INTERP_OK;
}
int Interp::convert_length_units(int g_code, setup_pointer settings) {
if (g_code == G_20) {
USE_LENGTH_UNITS(CANON_UNITS_INCHES);
if (settings->length_units != CANON_UNITS_INCHES) {
settings->length_units = CANON_UNITS_INCHES;
settings->current_x = (settings->current_x * INCH_PER_MM);
settings->current_y = (settings->current_y * INCH_PER_MM);
settings->current_z = (settings->current_z * INCH_PER_MM);
settings->program_x = (settings->program_x * INCH_PER_MM);
settings->program_y = (settings->program_y * INCH_PER_MM);
settings->program_z = (settings->program_z * INCH_PER_MM);
qc_scale(INCH_PER_MM);
settings->cutter_comp_radius *= INCH_PER_MM;
settings->axis_offset_x = (settings->axis_offset_x * INCH_PER_MM);
settings->axis_offset_y = (settings->axis_offset_y * INCH_PER_MM);
settings->axis_offset_z = (settings->axis_offset_z * INCH_PER_MM);
settings->origin_offset_x = (settings->origin_offset_x * INCH_PER_MM);
settings->origin_offset_y = (settings->origin_offset_y * INCH_PER_MM);
settings->origin_offset_z = (settings->origin_offset_z * INCH_PER_MM);
settings->u_current = (settings->u_current * INCH_PER_MM);
settings->v_current = (settings->v_current * INCH_PER_MM);
settings->w_current = (settings->w_current * INCH_PER_MM);
settings->u_axis_offset = (settings->u_axis_offset * INCH_PER_MM);
settings->v_axis_offset = (settings->v_axis_offset * INCH_PER_MM);
settings->w_axis_offset = (settings->w_axis_offset * INCH_PER_MM);
settings->u_origin_offset = (settings->u_origin_offset * INCH_PER_MM);
settings->v_origin_offset = (settings->v_origin_offset * INCH_PER_MM);
settings->w_origin_offset = (settings->w_origin_offset * INCH_PER_MM);
settings->tool_offset.tran.x = GET_EXTERNAL_TOOL_LENGTH_XOFFSET();
settings->tool_offset.tran.y = GET_EXTERNAL_TOOL_LENGTH_YOFFSET();
settings->tool_offset.tran.z = GET_EXTERNAL_TOOL_LENGTH_ZOFFSET();
settings->tool_offset.a = GET_EXTERNAL_TOOL_LENGTH_AOFFSET();
settings->tool_offset.b = GET_EXTERNAL_TOOL_LENGTH_BOFFSET();
settings->tool_offset.c = GET_EXTERNAL_TOOL_LENGTH_COFFSET();
settings->tool_offset.u = GET_EXTERNAL_TOOL_LENGTH_UOFFSET();
settings->tool_offset.v = GET_EXTERNAL_TOOL_LENGTH_VOFFSET();
settings->tool_offset.w = GET_EXTERNAL_TOOL_LENGTH_WOFFSET();
settings->feed_rate = GET_EXTERNAL_FEED_RATE();
}
} else if (g_code == G_21) {
USE_LENGTH_UNITS(CANON_UNITS_MM);
if (settings->length_units != CANON_UNITS_MM) {
settings->length_units = CANON_UNITS_MM;
settings->current_x = (settings->current_x * MM_PER_INCH);
settings->current_y = (settings->current_y * MM_PER_INCH);
settings->current_z = (settings->current_z * MM_PER_INCH);
settings->program_x = (settings->program_x * MM_PER_INCH);
settings->program_y = (settings->program_y * MM_PER_INCH);
settings->program_z = (settings->program_z * MM_PER_INCH);
qc_scale(MM_PER_INCH);
settings->cutter_comp_radius *= MM_PER_INCH;
settings->axis_offset_x = (settings->axis_offset_x * MM_PER_INCH);
settings->axis_offset_y = (settings->axis_offset_y * MM_PER_INCH);
settings->axis_offset_z = (settings->axis_offset_z * MM_PER_INCH);
settings->origin_offset_x = (settings->origin_offset_x * MM_PER_INCH);
settings->origin_offset_y = (settings->origin_offset_y * MM_PER_INCH);
settings->origin_offset_z = (settings->origin_offset_z * MM_PER_INCH);
settings->u_current = (settings->u_current * MM_PER_INCH);
settings->v_current = (settings->v_current * MM_PER_INCH);
settings->w_current = (settings->w_current * MM_PER_INCH);
settings->u_axis_offset = (settings->u_axis_offset * MM_PER_INCH);
settings->v_axis_offset = (settings->v_axis_offset * MM_PER_INCH);
settings->w_axis_offset = (settings->w_axis_offset * MM_PER_INCH);
settings->u_origin_offset = (settings->u_origin_offset * MM_PER_INCH);
settings->v_origin_offset = (settings->v_origin_offset * MM_PER_INCH);
settings->w_origin_offset = (settings->w_origin_offset * MM_PER_INCH);
settings->tool_offset.tran.x = GET_EXTERNAL_TOOL_LENGTH_XOFFSET();
settings->tool_offset.tran.y = GET_EXTERNAL_TOOL_LENGTH_YOFFSET();
settings->tool_offset.tran.z = GET_EXTERNAL_TOOL_LENGTH_ZOFFSET();
settings->tool_offset.a = GET_EXTERNAL_TOOL_LENGTH_AOFFSET();
settings->tool_offset.b = GET_EXTERNAL_TOOL_LENGTH_BOFFSET();
settings->tool_offset.c = GET_EXTERNAL_TOOL_LENGTH_COFFSET();
settings->tool_offset.u = GET_EXTERNAL_TOOL_LENGTH_UOFFSET();
settings->tool_offset.v = GET_EXTERNAL_TOOL_LENGTH_VOFFSET();
settings->tool_offset.w = GET_EXTERNAL_TOOL_LENGTH_WOFFSET();
settings->feed_rate = GET_EXTERNAL_FEED_RATE();
}
} else
ERS(NCE_BUG_CODE_NOT_G20_OR_G21);
return INTERP_OK;
}
int Interp::gen_settings(double *current, double *saved, std::string &cmd)
{
int i;
char buf[LINELEN];
for (i = 0; i < ACTIVE_SETTINGS; i++) {
if (saved[i] != current[i]) {
switch (i) {
case 0: break; case 1:
snprintf(buf,sizeof(buf)," F%.1f", saved[i]);
cmd += buf;
break;
case 2:
snprintf(buf,sizeof(buf)," S%.0f", saved[i]);
cmd += buf;
break;
}
}
}
return INTERP_OK;
}
int Interp::gen_g_codes(int *current, int *saved, std::string &cmd)
{
int i, val;
char buf[LINELEN];
for (i = 0; i < ACTIVE_G_CODES; i++) {
val = saved[i];
if (val != current[i]) {
switch (i) {
case 0:
break;
case 2: break;
case 12: break;
case 5: break;
case 1: break;
case 3: case 4: case 6: case 7: case 8: case 9: case 10: case 11: case 13: case 14: case 15:
if (val != -1) { if (val % 10) {
snprintf(buf,sizeof(buf)," G%d.%d", val / 10, val % 10);
} else {
snprintf(buf,sizeof(buf)," G%d", val / 10);
}
cmd += buf;
} else {
MSG("------ gen_g_codes BUG: index %d = -1!!\n",i);
}
break;
}
}
}
return INTERP_OK;
}
int Interp::gen_m_codes(int *current, int *saved, std::string &cmd)
{
int i,val;
char buf[LINELEN];
for (i = 0; i < ACTIVE_M_CODES; i++) {
val = saved[i];
if (val != current[i]) {
switch (i) {
case 0:
break;
case 1:
break;
case 3:
break;
case 2: case 4: case 5: case 6: case 7: case 8: if (val != -1) { snprintf(buf,sizeof(buf),"M%d\n", val);
cmd += buf;
} else {
MSG("------ gen_m_codes: index %d = -1!!\n",i);
}
break;
}
}
}
return INTERP_OK;
}
int Interp::save_settings(setup_pointer settings)
{
write_g_codes((block_pointer) NULL, settings);
write_m_codes((block_pointer) NULL, settings);
write_settings(settings);
active_g_codes((int *)settings->sub_context[settings->call_level].saved_g_codes);
active_m_codes((int *)settings->sub_context[settings->call_level].saved_m_codes);
active_settings((double *)settings->sub_context[settings->call_level].saved_settings);
return INTERP_OK;
}
int Interp::restore_settings(setup_pointer settings,
int from_level) {
CHKS((from_level < settings->call_level),
(_("BUG: cannot restore from a lower call level (%d) to a higher call level (%d)")),from_level,settings->call_level);
CHKS((from_level < 0), (_("BUG: restore from level %d !?")),from_level);
CHKS((settings->call_level < 0), (_("BUG: restore to level %d !?")),settings->call_level);
write_g_codes((block_pointer) NULL, settings);
write_m_codes((block_pointer) NULL, settings);
write_settings(settings);
std::string cmd;
if (settings->active_g_codes[5] != settings->sub_context[from_level].saved_g_codes[5]) {
char buf[LINELEN];
snprintf(buf,sizeof(buf), "G%d",settings->sub_context[from_level].saved_g_codes[5]/10);
CHKS(execute(buf) != INTERP_OK, _("M7x: restore_settings G20/G21 failed: '%s'"), cmd.c_str());
}
gen_settings((double *)settings->active_settings, (double *)settings->sub_context[from_level].saved_settings,cmd);
gen_m_codes((int *) settings->active_m_codes, (int *)settings->sub_context[from_level].saved_m_codes,cmd);
gen_g_codes((int *)settings->active_g_codes, (int *)settings->sub_context[from_level].saved_g_codes,cmd);
if (!cmd.empty()) {
char buf[cmd.size() + 1];
strncpy(buf, cmd.c_str(), sizeof(buf));
char *last = buf;
char *s;
while ((s = strtok_r(last, "\n", &last)) != NULL) {
int status = execute(s);
if (status != INTERP_OK) {
char currentError[LINELEN+1];
strcpy(currentError,getSavedError());
CHKS(status, _("M7x: restore_settings failed executing: '%s': %s"), s, currentError);
}
}
write_g_codes((block_pointer) NULL, settings);
write_m_codes((block_pointer) NULL, settings);
write_settings(settings);
}
return INTERP_OK;
}
int Interp::convert_m(block_pointer block, setup_pointer settings) {
int type;
double timeout;
if (IS_USER_MCODE(block,settings,5) &&
STEP_REMAPPED_IN_BLOCK(block, STEP_M_5) &&
ONCE_M(5)) {
return convert_remapped_code(block, settings, STEP_M_5, 'm',
block->m_modes[5]);
} else if ((block->m_modes[5] == 62) && ONCE_M(5)) {
CHKS((settings->cutter_comp_side),
(_("Cannot set motion output with cutter radius compensation on"))); CHKS((!block->p_flag), _("No valid P word with M62"));
SET_MOTION_OUTPUT_BIT(round_to_int(block->p_number));
} else if ((block->m_modes[5] == 63) && ONCE_M(5)) {
CHKS((settings->cutter_comp_side),
(_("Cannot set motion digital output with cutter radius compensation on"))); CHKS((!block->p_flag), _("No valid P word with M63"));
CLEAR_MOTION_OUTPUT_BIT(round_to_int(block->p_number));
} else if ((block->m_modes[5] == 64) && ONCE_M(5)){
CHKS((settings->cutter_comp_side),
(_("Cannot set auxiliary digital output with cutter radius compensation on"))); CHKS((!block->p_flag), _("No valid P word with M64"));
SET_AUX_OUTPUT_BIT(round_to_int(block->p_number));
} else if ((block->m_modes[5] == 65) && ONCE_M(5)) {
CHKS((settings->cutter_comp_side),
(_("Cannot set auxiliary digital output with cutter radius compensation on"))); CHKS((!block->p_flag), _("No valid P word with M65"));
CLEAR_AUX_OUTPUT_BIT(round_to_int(block->p_number));
} else if ((block->m_modes[5] == 66) && ONCE_M(5)){
CHKS(((block->p_flag) && (block->e_flag)),
NCE_BOTH_DIGITAL_AND_ANALOG_INPUT_SELECTED);
CHKS(((block->q_number <= 0) && (block->l_flag) && (round_to_int(block->l_number) > 0)),
NCE_ZERO_TIMEOUT_WITH_WAIT_NOT_IMMEDIATE);
CHKS(((block->e_flag) && (block->l_flag) && (round_to_int(block->l_number) != 0)),
NCE_ANALOG_INPUT_WITH_WAIT_NOT_IMMEDIATE);
CHKS( ((block->p_flag) && (round_to_int(block->p_number) < 0)) ||
((block->e_flag) && (round_to_int(block->e_number) < 0)) ||
((!block->p_flag) && (!block->e_flag)) ,
NCE_INVALID_OR_MISSING_P_AND_E_WORDS_FOR_WAIT_INPUT);
if (block->p_flag) { if (round_to_int(block->p_number) < 0) ERS(_("invalid P-word with M66"));
if (block->l_flag) {
type = round_to_int(block->l_number);
} else {
type = WAIT_MODE_IMMEDIATE;
}
if (block->q_number > 0) {
timeout = block->q_number;
} else {
timeout = 0;
}
CHKS((settings->cutter_comp_side),
(_("Cannot wait for digital input with cutter radius compensation on")));
int ret = WAIT(round_to_int(block->p_number), DIGITAL_INPUT, type, timeout);
CHKS((ret == -1), NCE_DIGITAL_INPUT_INVALID_ON_M66);
if (ret == 0) {
settings->input_flag = true;
settings->input_index = round_to_int(block->p_number);
settings->input_digital = true;
}
} else if (round_to_int(block->e_number) >= 0) { CHKS((settings->cutter_comp_side),
(_("Cannot wait for analog input with cutter radius compensation on")));
int ret = WAIT(round_to_int(block->e_number), ANALOG_INPUT, 0, 0); CHKS((ret == -1), NCE_ANALOG_INPUT_INVALID_ON_M66);
if (ret == 0) {
settings->input_flag = true;
settings->input_index = round_to_int(block->e_number);
settings->input_digital = false;
}
}
} else if ((block->m_modes[5] == 67) && ONCE_M(5)) {
CHKS((settings->cutter_comp_side),
(_("Cannot set motion analog output with cutter radius compensation on"))); CHKS((!block->e_flag) || (round_to_int(block->e_number) < 0), (_("Invalid analog index with M67")));
SET_MOTION_OUTPUT_VALUE(round_to_int(block->e_number), block->q_number);
} else if ((block->m_modes[5] == 68) && ONCE_M(5)) {
CHKS((settings->cutter_comp_side),
(_("Cannot set auxiliary analog output with cutter radius compensation on"))); CHKS((!block->e_flag) || (round_to_int(block->e_number) < 0), (_("Invalid analog index with M68")));
SET_AUX_OUTPUT_VALUE(round_to_int(block->e_number), block->q_number);
}
if ((block->m_modes[6] != -1) && ONCE_M(6)){
int toolno;
bool remapped_in_block = STEP_REMAPPED_IN_BLOCK(block, STEP_M_6);
switch (block->m_modes[6]) {
case 6:
if (IS_USER_MCODE(block,settings,6) && remapped_in_block) {
return convert_remapped_code(block,settings,
STEP_M_6,
'm',
block->m_modes[6]);
} else {
CONTROLLING_BLOCK(*settings).builtin_used = !remapped_in_block;
CHP(convert_tool_change(settings));
}
break;
case 61:
if (IS_USER_MCODE(block,settings,6) && remapped_in_block) {
return convert_remapped_code(block, settings, STEP_M_6,'m',
block->m_modes[6]);
} else {
CONTROLLING_BLOCK(*settings).builtin_used = !remapped_in_block;
toolno = round_to_int(block->q_number);
CHKS((toolno < 0), (_("Need non-negative Q-word to specify tool number with M61")));
int pocket;
CHP((find_tool_pocket(settings, toolno, &pocket)));
settings->current_pocket = pocket;
settings->toolchange_flag = true;
CHANGE_TOOL_NUMBER(settings->current_pocket);
set_tool_parameters();
}
break;
default:
if (IS_USER_MCODE(block,settings,6)) {
return convert_remapped_code(block, settings, STEP_M_6,'m',
block->m_modes[6]);
}
}
}
if (FEATURE(RETAIN_G43)) {
if ((settings->active_g_codes[9] == G_43) && ONCE(STEP_RETAIN_G43)) {
if(settings->selected_pocket > 0) {
struct block_struct g43;
init_block(&g43);
block->g_modes[_gees[G_43]] = G_43;
CHP(convert_tool_length_offset(G_43, &g43, settings));
} else {
struct block_struct g49;
init_block(&g49);
block->g_modes[_gees[G_49]] = G_49;
CHP(convert_tool_length_offset(G_49, &g49, settings));
}
}
}
if (IS_USER_MCODE(block,settings,7) && ONCE_M(7)) {
return convert_remapped_code(block, settings, STEP_M_7, 'm',
block->m_modes[7]);
} else if ((block->m_modes[7] == 3) && ONCE_M(7)) {
if (block->dollar_flag){
CHKS((block->dollar_number >= settings->num_spindles || block->dollar_number < 0),
(_("Spindle ($) number out of range in M3 Command\nnum_spindles =%i. $=%d\n")),settings->num_spindles,(int)block->dollar_number);
enqueue_START_SPINDLE_CLOCKWISE(block->dollar_number);
settings->spindle_turning[(int)block->dollar_number] = CANON_CLOCKWISE;
} else {
for (int i = 0; i < settings->num_spindles; i++){
enqueue_START_SPINDLE_CLOCKWISE(i);
settings->spindle_turning[i] = CANON_CLOCKWISE;
}
}
} else if ((block->m_modes[7] == 4) && ONCE_M(7)) {
if (block->dollar_flag){
CHKS((block->dollar_number >= settings->num_spindles || block->dollar_number < 0),
(_("Spindle ($) number out of range in M4 Command")));
enqueue_START_SPINDLE_COUNTERCLOCKWISE(block->dollar_number);
settings->spindle_turning[(int)block->dollar_number] = CANON_COUNTERCLOCKWISE;
} else {
for (int i = 0; i < settings->num_spindles; i++){
enqueue_START_SPINDLE_COUNTERCLOCKWISE(i);
settings->spindle_turning[i] = CANON_COUNTERCLOCKWISE;
}
}
} else if ((block->m_modes[7] == 5) && ONCE_M(7)){
if (block->dollar_flag){
CHKS((block->dollar_number >= settings->num_spindles || block->dollar_number < 0),
(_("Spindle ($) number out of range in M5 Command")));
enqueue_STOP_SPINDLE_TURNING(block->dollar_number);
} else {
for (int i = 0; i < settings->num_spindles; i++){
settings->spindle_turning[i] = CANON_STOPPED;
enqueue_STOP_SPINDLE_TURNING(i);
}
}
} else if ((block->m_modes[7] == 19) && ONCE_M(7)) {
for (int i = 0; i < settings->num_spindles; i++)
settings->spindle_turning[i] = CANON_STOPPED;
if (block->dollar_flag){
CHKS((block->dollar_number >= settings->num_spindles || block->dollar_number < 0),
(_("Spindle ($) number out of range in M19 Command")));
}
if (block->r_flag || block->p_flag)
enqueue_ORIENT_SPINDLE(block->dollar_flag ? block->dollar_number : 0,
block->r_flag ? (block->r_number + settings->orient_offset) : settings->orient_offset,
block->p_flag ? block->p_number : 0);
if (block->q_flag) {
CHKS((block->q_number <= 0.0),(_("Q word with M19 requires a value > 0")));
enqueue_WAIT_ORIENT_SPINDLE_COMPLETE(block->dollar_flag ? block->dollar_number : 0,
block->q_number);
}
} else if ((block->m_modes[7] == 70) || (block->m_modes[7] == 73)) {
save_settings(&_setup);
_setup.sub_context[_setup.call_level].context_status |= CONTEXT_VALID;
if (block->m_modes[7] == 73) {
if (_setup.call_level == 0) {
MSG("Warning - M73 at top level: nothing to return to; storing context anyway\n");
} else {
_setup.sub_context[_setup.call_level].context_status |= CONTEXT_RESTORE_ON_RETURN;
}
}
} else if ((block->m_modes[7] == 71) && ONCE_M(7)) {
_setup.sub_context[_setup.call_level].context_status &= ~CONTEXT_VALID;
} else if ((block->m_modes[7] == 72) && ONCE_M(7)) {
CHKS((!(_setup.sub_context[_setup.call_level].context_status & CONTEXT_VALID)),
(_("Cannot restore context from invalid stack frame - missing M70/M73?")));
CHP(restore_settings(&_setup, _setup.call_level));
}
if (IS_USER_MCODE(block,settings,8) && ONCE_M(8)) {
return convert_remapped_code(block, settings, STEP_M_8, 'm',
block->m_modes[8]);
} else if ((block->m_modes[8] == 7) && ONCE_M(8)){
enqueue_MIST_ON();
settings->mist = true;
} else if ((block->m_modes[8] == 8) && ONCE_M(8)) {
enqueue_FLOOD_ON();
settings->flood = true;
} else if ((block->m_modes[8] == 9) && ONCE_M(8)) {
enqueue_MIST_OFF();
settings->mist = false;
enqueue_FLOOD_OFF();
settings->flood = false;
}
if (IS_USER_MCODE(block,settings,9) && ONCE_M(9)) {
return convert_remapped_code(block, settings, STEP_M_9, 'm',
block->m_modes[9]);
} else if ((block->m_modes[9] == 48) && ONCE_M(9)){
CHKS((settings->cutter_comp_side),
(_("Cannot enable overrides with cutter radius compensation on"))); ENABLE_FEED_OVERRIDE();
settings->feed_override = true;
for (int s = 0; s < settings->num_spindles; s++){
settings->speed_override[s] = true;
ENABLE_SPEED_OVERRIDE(s);
}
} else if ((block->m_modes[9] == 49) && ONCE_M(9)){
CHKS((settings->cutter_comp_side),
(_("Cannot disable overrides with cutter radius compensation on"))); DISABLE_FEED_OVERRIDE();
settings->feed_override = false;
for (int s = 0; s < settings->num_spindles; s++){
settings->speed_override[s] = false;
DISABLE_SPEED_OVERRIDE(s);
}
}
if ((block->m_modes[9] == 50) && ONCE_M(9)){
if (block->p_number != 0) {
CHKS((settings->cutter_comp_side),
(_("Cannot enable overrides with cutter radius compensation on"))); ENABLE_FEED_OVERRIDE();
settings->feed_override = true;
} else {
CHKS((settings->cutter_comp_side),
(_("Cannot disable overrides with cutter radius compensation on"))); DISABLE_FEED_OVERRIDE();
settings->feed_override = false;
}
}
if ((block->m_modes[9] == 51) && ONCE_M(9)){
int e = -1;
if (block->dollar_flag){
CHKS((block->dollar_number <= 0 || block->dollar_number >= settings-> num_spindles),
(_("Invalid spindle ($) number in M51 command")));
e = block->dollar_number;
}
if (block->p_number != 0) {
CHKS((settings->cutter_comp_side),
(_("Cannot enable overrides with cutter radius compensation on"))); for (int s = 0; s < settings->num_spindles; s++){
if (e == -1 or s == e){
ENABLE_SPEED_OVERRIDE(s);
settings->speed_override[s] = true;
}
}
} else {
CHKS((settings->cutter_comp_side),
(_("Cannot disable overrides with cutter radius compensation on"))); for (int s = 0; s < settings->num_spindles; s++){
if (e == -1 or s == e){
DISABLE_SPEED_OVERRIDE(s);
settings->speed_override[s] = false;
}
}
}
}
if ((block->m_modes[9] == 52) && ONCE_M(9)){
if (block->p_number != 0) {
CHKS((settings->cutter_comp_side),
(_("Cannot enable overrides with cutter radius compensation on"))); ENABLE_ADAPTIVE_FEED();
settings->adaptive_feed = true;
} else {
CHKS((settings->cutter_comp_side),
(_("Cannot disable overrides with cutter radius compensation on"))); DISABLE_ADAPTIVE_FEED();
settings->adaptive_feed = false;
}
}
if ((block->m_modes[9] == 53) && ONCE_M(9)){
if (block->p_number != 0) {
CHKS((settings->cutter_comp_side),
(_("Cannot enable overrides with cutter radius compensation on"))); ENABLE_FEED_HOLD();
settings->feed_hold = true;
} else {
CHKS((settings->cutter_comp_side),
(_("Cannot disable overrides with cutter radius compensation on"))); DISABLE_FEED_HOLD();
settings->feed_hold = false;
}
}
if (IS_USER_MCODE(block,settings,10) && ONCE_M(10)) {
return convert_remapped_code(block,settings,STEP_M_10,'m',
block->m_modes[10]);
} else if ((block->m_modes[10] != -1) && ONCE_M(10)){
int index = block->m_modes[10];
if (USER_DEFINED_FUNCTION[index - 100] == 0) {
CHKS(1, NCE_UNKNOWN_M_CODE_USED,index);
}
enqueue_M_USER_COMMAND(index,block->p_number,block->q_number);
}
return INTERP_OK;
}
int Interp::convert_modal_0(int code, block_pointer block, setup_pointer settings) {
if (code == G_10) {
if(block->l_number == 1 || block->l_number == 10 || block->l_number == 11)
CHP(convert_setup_tool(block, settings));
else
CHP(convert_setup(block, settings));
} else if ((code == G_28) || (code == G_30)) {
CHP(convert_home(code, block, settings));
} else if ((code == G_28_1) || (code == G_30_1)) {
CHP(convert_savehome(code, block, settings));
} else if ((code == G_52) ||
(code == G_92) || (code == G_92_1) ||
(code == G_92_2) || (code == G_92_3)) {
CHP(convert_axis_offsets(code, block, settings));
} else if (code == G_5_3) {
CHP(convert_nurbs(code, block, settings));
} else if ((code == G_4) || (code == G_53));
else
ERS(NCE_BUG_CODE_NOT_G4_G10_G28_G30_G52_G53_OR_G92_SERIES);
return INTERP_OK;
}
int Interp::convert_motion(int motion, block_pointer block, setup_pointer settings) {
int ai = block->a_flag && (-1 != settings->a_indexer_jnum);
int bi = block->b_flag && (-1 != settings->b_indexer_jnum);
int ci = block->c_flag && (-1 != settings->c_indexer_jnum);
if (motion != G_0) {
CHKS((ai), (_("Indexing axis %c can only be moved with G0")), 'A');
CHKS((bi), (_("Indexing axis %c can only be moved with G0")), 'B');
CHKS((ci), (_("Indexing axis %c can only be moved with G0")), 'C');
}
int xyzuvw_flag = (block->x_flag || block->y_flag || block->z_flag ||
block->u_flag || block->v_flag || block->w_flag);
CHKS((ai && (xyzuvw_flag || block->b_flag || block->c_flag)),
(_("Indexing axis %c can only be moved alone")), 'A');
CHKS((bi && (xyzuvw_flag || block->a_flag || block->c_flag)),
(_("Indexing axis %c can only be moved alone")), 'B');
CHKS((ci && (xyzuvw_flag || block->a_flag || block->b_flag)),
(_("Indexing axis %c can only be moved alone")), 'C');
if (!is_a_cycle(motion))
settings->cycle_il_flag = false;
if (ai || bi || ci) {
int anum=-1,jnum=-1;
if ( ai) {anum = 3; jnum = settings->a_indexer_jnum;}
else if (bi) {anum = 4; jnum = settings->b_indexer_jnum;}
else if (ci) {anum = 5; jnum = settings->c_indexer_jnum;}
CHP(convert_straight_indexer(anum, jnum, block, settings));
} else if ((motion == G_0) || (motion == G_1) || (motion == G_33) || (motion == G_33_1) || (motion == G_76)) {
CHP(convert_straight(motion, block, settings));
} else if ((motion == G_3) || (motion == G_2)) {
CHP(convert_arc(motion, block, settings));
} else if (motion == G_38_2 || motion == G_38_3 ||
motion == G_38_4 || motion == G_38_5) {
CHP(convert_probe(block, motion, settings));
} else if (motion == G_80) {
#ifdef DEBUG_EMC
enqueue_COMMENT("interpreter: motion mode set to none");
#endif
settings->motion_mode = G_80;
} else if (IS_USER_GCODE(motion)) {
CHP(convert_remapped_code(block, settings, STEP_MOTION, 'g', motion));
} else if (is_a_cycle(motion)) {
CHP(convert_cycle(motion, block, settings));
} else if ((motion == G_5) || (motion == G_5_1)) {
CHP(convert_spline(motion, block, settings));
} else if (motion == G_5_2) {
CHP(convert_nurbs(motion, block, settings));
} else {
ERS(NCE_BUG_UNKNOWN_MOTION_CODE);
}
return INTERP_OK;
}
int Interp::convert_probe(block_pointer block, int g_code,
setup_pointer settings) {
double end_x;
double end_y;
double end_z;
double AA_end;
double BB_end;
double CC_end;
double u_end;
double v_end;
double w_end;
unsigned char probe_type = g_code - G_38_2;
CHKS((settings->cutter_comp_side),
NCE_CANNOT_PROBE_WITH_CUTTER_RADIUS_COMP_ON);
CHKS((settings->feed_rate == 0.0), NCE_CANNOT_PROBE_WITH_ZERO_FEED_RATE);
CHKS(settings->feed_mode == UNITS_PER_REVOLUTION,
_("Cannot probe with feed per rev mode"));
CHP(find_ends(block, settings, &end_x, &end_y, &end_z,
&AA_end, &BB_end, &CC_end,
&u_end, &v_end, &w_end));
CHKS(((!(probe_type & 1)) &&
settings->current_x == end_x && settings->current_y == end_y &&
settings->current_z == end_z && settings->AA_current == AA_end &&
settings->BB_current == BB_end && settings->CC_current == CC_end &&
settings->u_current == u_end && settings->v_current == v_end &&
settings->w_current == w_end),
NCE_START_POINT_TOO_CLOSE_TO_PROBE_POINT);
TURN_PROBE_ON();
STRAIGHT_PROBE(block->line_number, end_x, end_y, end_z,
AA_end, BB_end, CC_end,
u_end, v_end, w_end, probe_type);
TURN_PROBE_OFF();
settings->motion_mode = g_code;
settings->probe_flag = true;
return INTERP_OK;
}
int Interp::convert_retract_mode(int g_code, setup_pointer settings) {
CHKS((settings->cutter_comp_side),
(_("Cannot change retract mode with cutter radius compensation on")));
if (g_code == G_98) {
#ifdef DEBUG_EMC
enqueue_COMMENT("interpreter: retract mode set to old_z");
#endif
settings->retract_mode = OLD_Z;
} else if (g_code == G_99) {
#ifdef DEBUG_EMC
enqueue_COMMENT("interpreter: retract mode set to r_plane");
#endif
settings->retract_mode = R_PLANE;
} else
ERS(NCE_BUG_CODE_NOT_G98_OR_G99);
return INTERP_OK;
}
int Interp::convert_setup_tool(block_pointer block, setup_pointer settings) {
int pocket = -1, toolno;
int q;
double tx, ty, tz, ta, tb, tc, tu, tv, tw;
int direct = block->l_number == 1;
is_near_int(&toolno, block->p_number);
CHP((find_tool_pocket(settings, toolno, &pocket)));
CHKS(!(block->x_flag || block->y_flag || block->z_flag ||
block->a_flag || block->b_flag || block->c_flag ||
block->u_flag || block->v_flag || block->w_flag ||
block->r_flag || block->q_flag || block->i_flag ||
block->j_flag),
_("G10 L1 without offsets has no effect"));
if(direct) {
if(block->x_flag)
settings->tool_table[pocket].offset.tran.x = PROGRAM_TO_USER_LEN(block->x_number);
if(block->y_flag)
settings->tool_table[pocket].offset.tran.y = PROGRAM_TO_USER_LEN(block->y_number);
if(block->z_flag)
settings->tool_table[pocket].offset.tran.z = PROGRAM_TO_USER_LEN(block->z_number);
if(block->a_flag)
settings->tool_table[pocket].offset.a = PROGRAM_TO_USER_ANG(block->a_number);
if(block->b_flag)
settings->tool_table[pocket].offset.b = PROGRAM_TO_USER_ANG(block->b_number);
if(block->c_flag)
settings->tool_table[pocket].offset.c = PROGRAM_TO_USER_ANG(block->c_number);
if(block->u_flag)
settings->tool_table[pocket].offset.u = PROGRAM_TO_USER_LEN(block->u_number);
if(block->v_flag)
settings->tool_table[pocket].offset.v = PROGRAM_TO_USER_LEN(block->v_number);
if(block->w_flag)
settings->tool_table[pocket].offset.w = PROGRAM_TO_USER_LEN(block->w_number);
} else {
int to_fixture = block->l_number == 11;
int destination_system = to_fixture? 9 : settings->origin_index;
find_current_in_system_without_tlo(settings, destination_system,
&tx, &ty, &tz,
&ta, &tb, &tc,
&tu, &tv, &tw);
if ( to_fixture && settings->parameters[5210]) {
tx += USER_TO_PROGRAM_LEN(settings->parameters[5211]);
ty += USER_TO_PROGRAM_LEN(settings->parameters[5212]);
tz += USER_TO_PROGRAM_LEN(settings->parameters[5213]);
ta += USER_TO_PROGRAM_ANG(settings->parameters[5214]);
tb += USER_TO_PROGRAM_ANG(settings->parameters[5215]);
tc += USER_TO_PROGRAM_ANG(settings->parameters[5216]);
tu += USER_TO_PROGRAM_LEN(settings->parameters[5217]);
tv += USER_TO_PROGRAM_LEN(settings->parameters[5218]);
tw += USER_TO_PROGRAM_LEN(settings->parameters[5219]);
}
if(block->x_flag && block->y_flag) {
tx -= block->x_number;
ty -= block->y_number;
rotate(&tx, &ty, settings->parameters[5210 + destination_system * 20]);
settings->tool_table[pocket].offset.tran.x = PROGRAM_TO_USER_LEN(tx);
settings->tool_table[pocket].offset.tran.y = PROGRAM_TO_USER_LEN(ty);
} else if(block->x_flag) {
double ox, oy;
ox = USER_TO_PROGRAM_LEN(settings->tool_table[pocket].offset.tran.x);
oy = USER_TO_PROGRAM_LEN(settings->tool_table[pocket].offset.tran.y);
rotate(&ox, &oy, -settings->parameters[5210 + destination_system * 20]);
ox = 0;
rotate(&ox, &oy, settings->parameters[5210 + destination_system * 20]);
tx -= block->x_number;
ty = 0;
rotate(&tx, &ty, settings->parameters[5210 + destination_system * 20]);
settings->tool_table[pocket].offset.tran.x = PROGRAM_TO_USER_LEN(tx + ox);
settings->tool_table[pocket].offset.tran.y = PROGRAM_TO_USER_LEN(ty + oy);
} else if(block->y_flag) {
double ox, oy;
ox = USER_TO_PROGRAM_LEN(settings->tool_table[pocket].offset.tran.x);
oy = USER_TO_PROGRAM_LEN(settings->tool_table[pocket].offset.tran.y);
rotate(&ox, &oy, -settings->parameters[5210 + destination_system * 20]);
oy = 0;
rotate(&ox, &oy, settings->parameters[5210 + destination_system * 20]);
ty -= block->y_number;
tx = 0;
rotate(&tx, &ty, settings->parameters[5210 + destination_system * 20]);
settings->tool_table[pocket].offset.tran.x = PROGRAM_TO_USER_LEN(tx + ox);
settings->tool_table[pocket].offset.tran.y = PROGRAM_TO_USER_LEN(ty + oy);
}
if(block->z_flag)
settings->tool_table[pocket].offset.tran.z = PROGRAM_TO_USER_LEN(tz - block->z_number);
if(block->a_flag)
settings->tool_table[pocket].offset.a = PROGRAM_TO_USER_ANG(ta - block->a_number);
if(block->b_flag)
settings->tool_table[pocket].offset.b = PROGRAM_TO_USER_ANG(tb - block->b_number);
if(block->c_flag)
settings->tool_table[pocket].offset.c = PROGRAM_TO_USER_ANG(tc - block->c_number);
if(block->u_flag)
settings->tool_table[pocket].offset.u = PROGRAM_TO_USER_LEN(tu - block->u_number);
if(block->v_flag)
settings->tool_table[pocket].offset.v = PROGRAM_TO_USER_LEN(tv - block->v_number);
if(block->w_flag)
settings->tool_table[pocket].offset.w = PROGRAM_TO_USER_LEN(tw - block->w_number);
}
if(block->r_flag) settings->tool_table[pocket].diameter = PROGRAM_TO_USER_LEN(block->r_number) * 2.;
if(block->i_flag) settings->tool_table[pocket].frontangle = block->i_number;
if(block->j_flag) settings->tool_table[pocket].backangle = block->j_number;
if(block->q_number != -1.0) {
CHKS((!is_near_int(&q, block->q_number)), _("Q number in G10 is not an integer"));
CHKS((q > 9), _("Invalid tool orientation"));
settings->tool_table[pocket].orientation = q;
}
SET_TOOL_TABLE_ENTRY(pocket,
settings->tool_table[pocket].toolno,
settings->tool_table[pocket].offset,
settings->tool_table[pocket].diameter,
settings->tool_table[pocket].frontangle,
settings->tool_table[pocket].backangle,
settings->tool_table[pocket].orientation);
if ((!settings->random_toolchanger) && (settings->current_pocket == pocket)) {
settings->tool_table[0] = settings->tool_table[pocket];
}
if (settings->random_toolchanger)
if (settings->tool_table[0].toolno >= 0) {
settings->parameters[5400] = settings->tool_table[0].toolno;
} else {
settings->parameters[5400] = -1;
} else {
if (settings->tool_table[0].toolno > 0) {
settings->parameters[5400] = settings->tool_table[0].toolno;
} else {
settings->parameters[5400] = 0;
}
}
settings->parameters[5401] = settings->tool_table[0].offset.tran.x;
settings->parameters[5402] = settings->tool_table[0].offset.tran.y;
settings->parameters[5403] = settings->tool_table[0].offset.tran.z;
settings->parameters[5404] = settings->tool_table[0].offset.a;
settings->parameters[5405] = settings->tool_table[0].offset.b;
settings->parameters[5406] = settings->tool_table[0].offset.c;
settings->parameters[5407] = settings->tool_table[0].offset.u;
settings->parameters[5408] = settings->tool_table[0].offset.v;
settings->parameters[5409] = settings->tool_table[0].offset.w;
settings->parameters[5410] = settings->tool_table[0].diameter;
settings->parameters[5411] = settings->tool_table[0].frontangle;
settings->parameters[5412] = settings->tool_table[0].backangle;
settings->parameters[5413] = settings->tool_table[0].orientation;
if ( !_setup.random_toolchanger
&& pocket == settings->current_pocket) {
SET_TOOL_TABLE_ENTRY(0,
settings->tool_table[pocket].toolno,
settings->tool_table[pocket].offset,
settings->tool_table[pocket].diameter,
settings->tool_table[pocket].frontangle,
settings->tool_table[pocket].backangle,
settings->tool_table[pocket].orientation);
}
return INTERP_OK;
}
int Interp::convert_setup(block_pointer block, setup_pointer settings) {
double x;
double y;
double z;
double a;
double b;
double c;
double u, v, w;
double r;
double *parameters;
int p_int;
double cx, cy, cz, ca, cb, cc, cu, cv, cw;
CHKS((block->i_flag || block->j_flag), _("I J words not allowed with G10 L2"));
parameters = settings->parameters;
p_int = (int) (block->p_number + 0.0001);
if (p_int == 0) {
p_int = settings->origin_index;
}
CHKS((block->l_number == 20 && block->a_flag && settings->a_axis_wrapped &&
(block->a_number <= -360.0 || block->a_number >= 360.0)),
(_("Invalid absolute position %5.2f for wrapped rotary axis %c")), block->a_number, 'A');
CHKS((block->l_number == 20 && block->b_flag && settings->b_axis_wrapped &&
(block->b_number <= -360.0 || block->b_number >= 360.0)),
(_("Invalid absolute position %5.2f for wrapped rotary axis %c")), block->b_number, 'B');
CHKS((block->l_number == 20 && block->c_flag && settings->c_axis_wrapped &&
(block->c_number <= -360.0 || block->c_number >= 360.0)),
(_("Invalid absolute position %5.2f for wrapped rotary axis %c")), block->c_number, 'C');
CHKS((settings->cutter_comp_side && p_int == settings->origin_index),
(_("Cannot change the active coordinate system with cutter radius compensation on")));
find_current_in_system(settings, p_int,
&cx, &cy, &cz,
&ca, &cb, &cc,
&cu, &cv, &cw);
if (block->r_flag) {
CHKS((block->l_number == 20), _("R not allowed in G10 L20"));
r = block->r_number;
parameters[5210 + (p_int * 20)] = r;
} else
r = parameters[5210 + (p_int * 20)];
if (block->l_number == 20) {
double oldx = cx, oldy = cy;
x = cx;
y = cy;
if (block->x_flag) {
x = block->x_number;
}
if (block->y_flag) {
y = block->y_number;
}
rotate(&oldx, &oldy, r);
rotate(&x, &y, r);
x = oldx + USER_TO_PROGRAM_LEN(parameters[5201 + (p_int * 20)]) - x;
y = oldy + USER_TO_PROGRAM_LEN(parameters[5202 + (p_int * 20)]) - y;
parameters[5201 + (p_int * 20)] = PROGRAM_TO_USER_LEN(x);
parameters[5202 + (p_int * 20)] = PROGRAM_TO_USER_LEN(y);
if (p_int == settings->origin_index) {
rotate(&settings->current_x, &settings->current_y, settings->rotation_xy);
settings->rotation_xy = 0;
}
} else {
if (block->x_flag) {
x = block->x_number;
parameters[5201 + (p_int * 20)] = PROGRAM_TO_USER_LEN(x);
} else {
x = USER_TO_PROGRAM_LEN(parameters[5201 + (p_int * 20)]);
}
if (block->y_flag) {
y = block->y_number;
parameters[5202 + (p_int * 20)] = PROGRAM_TO_USER_LEN(y);
} else {
y = USER_TO_PROGRAM_LEN(parameters[5202 + (p_int * 20)]);
}
}
if (block->z_flag) {
z = block->z_number;
if (block->l_number == 20) z = cz + USER_TO_PROGRAM_LEN(parameters[5203 + (p_int * 20)]) - z;
parameters[5203 + (p_int * 20)] = PROGRAM_TO_USER_LEN(z);
} else
z = USER_TO_PROGRAM_LEN(parameters[5203 + (p_int * 20)]);
if (block->a_flag) {
a = block->a_number;
if (block->l_number == 20) a = ca + USER_TO_PROGRAM_ANG(parameters[5204 + (p_int * 20)]) - a;
parameters[5204 + (p_int * 20)] = PROGRAM_TO_USER_ANG(a);
} else
a = USER_TO_PROGRAM_ANG(parameters[5204 + (p_int * 20)]);
if (block->b_flag) {
b = block->b_number;
if (block->l_number == 20) b = cb + USER_TO_PROGRAM_ANG(parameters[5205 + (p_int * 20)]) - b;
parameters[5205 + (p_int * 20)] = PROGRAM_TO_USER_ANG(b);
} else
b = USER_TO_PROGRAM_ANG(parameters[5205 + (p_int * 20)]);
if (block->c_flag) {
c = block->c_number;
if (block->l_number == 20) c = cc + USER_TO_PROGRAM_ANG(parameters[5206 + (p_int * 20)]) - c;
parameters[5206 + (p_int * 20)] = PROGRAM_TO_USER_ANG(c);
} else
c = USER_TO_PROGRAM_ANG(parameters[5206 + (p_int * 20)]);
if (block->u_flag) {
u = block->u_number;
if (block->l_number == 20) u = cu + USER_TO_PROGRAM_LEN(parameters[5207 + (p_int * 20)]) - u;
parameters[5207 + (p_int * 20)] = PROGRAM_TO_USER_LEN(u);
} else
u = USER_TO_PROGRAM_LEN(parameters[5207 + (p_int * 20)]);
if (block->v_flag) {
v = block->v_number;
if (block->l_number == 20) v = cv + USER_TO_PROGRAM_LEN(parameters[5208 + (p_int * 20)]) - v;
parameters[5208 + (p_int * 20)] = PROGRAM_TO_USER_LEN(v);
} else
v = USER_TO_PROGRAM_LEN(parameters[5208 + (p_int * 20)]);
if (block->w_flag) {
w = block->w_number;
if (block->l_number == 20) w = cw + USER_TO_PROGRAM_LEN(parameters[5209 + (p_int * 20)]) - w;
parameters[5209 + (p_int * 20)] = PROGRAM_TO_USER_LEN(w);
} else
w = USER_TO_PROGRAM_LEN(parameters[5209 + (p_int * 20)]);
if (p_int == settings->origin_index) {
rotate(&settings->current_x, &settings->current_y, settings->rotation_xy);
settings->current_x += settings->origin_offset_x;
settings->current_y += settings->origin_offset_y;
settings->current_z += settings->origin_offset_z;
settings->AA_current += settings->AA_origin_offset;
settings->BB_current += settings->BB_origin_offset;
settings->CC_current += settings->CC_origin_offset;
settings->u_current += settings->u_origin_offset;
settings->v_current += settings->v_origin_offset;
settings->w_current += settings->w_origin_offset;
settings->origin_offset_x = x;
settings->origin_offset_y = y;
settings->origin_offset_z = z;
settings->AA_origin_offset = a;
settings->BB_origin_offset = b;
settings->CC_origin_offset = c;
settings->u_origin_offset = u;
settings->v_origin_offset = v;
settings->w_origin_offset = w;
settings->current_x -= x;
settings->current_y -= y;
settings->current_z -= z;
settings->AA_current -= a;
settings->BB_current -= b;
settings->CC_current -= c;
settings->u_current -= u;
settings->v_current -= v;
settings->w_current -= w;
SET_G5X_OFFSET(p_int, x, y, z, a, b, c, u, v, w);
rotate(&settings->current_x, &settings->current_y, - r);
settings->rotation_xy = r;
SET_XY_ROTATION(settings->rotation_xy);
}
#ifdef DEBUG_EMC
else
enqueue_COMMENT("interpreter: setting coordinate system origin");
#endif
return INTERP_OK;
}
int Interp::convert_set_plane(int g_code, setup_pointer settings) {
CHKS((settings->cutter_comp_side && g_code == G_17 && settings->plane != CANON_PLANE_XY),
NCE_CANNOT_CHANGE_PLANES_WITH_CUTTER_RADIUS_COMP_ON);
CHKS((settings->cutter_comp_side && g_code == G_18 && settings->plane != CANON_PLANE_XZ),
NCE_CANNOT_CHANGE_PLANES_WITH_CUTTER_RADIUS_COMP_ON);
CHKS((settings->cutter_comp_side && g_code == G_19 && settings->plane != CANON_PLANE_YZ),
NCE_CANNOT_CHANGE_PLANES_WITH_CUTTER_RADIUS_COMP_ON);
CHKS((settings->cutter_comp_side && g_code == G_19),
NCE_RADIUS_COMP_ONLY_IN_XY_OR_XZ);
if (g_code == G_17) {
SELECT_PLANE(CANON_PLANE_XY);
settings->plane = CANON_PLANE_XY;
} else if (g_code == G_18) {
SELECT_PLANE(CANON_PLANE_XZ);
settings->plane = CANON_PLANE_XZ;
} else if (g_code == G_19) {
SELECT_PLANE(CANON_PLANE_YZ);
settings->plane = CANON_PLANE_YZ;
} else if (g_code == G_17_1) {
SELECT_PLANE(CANON_PLANE_UV);
settings->plane = CANON_PLANE_UV;
} else if (g_code == G_18_1) {
SELECT_PLANE(CANON_PLANE_UW);
settings->plane = CANON_PLANE_UW;
} else if (g_code == G_19_1) {
SELECT_PLANE(CANON_PLANE_VW);
settings->plane = CANON_PLANE_VW;
} else
ERS(NCE_BUG_CODE_NOT_G17_G18_OR_G19);
return INTERP_OK;
}
int Interp::convert_speed(int spindle, block_pointer block, setup_pointer settings){
if (spindle >= 0 && spindle < settings->num_spindles){
enqueue_SET_SPINDLE_SPEED(spindle, block->s_number);
settings->speed[spindle] = block->s_number;
}
return INTERP_OK;
}
int Interp::convert_spindle_mode(int dollar_number, block_pointer block, setup_pointer settings)
{
for (int s = 0; s < settings->num_spindles; s++){
if (dollar_number == -1 || s == dollar_number){
if(block->g_modes[14] == G_97) {
settings->spindle_mode[s] = CONSTANT_RPM;
enqueue_SET_SPINDLE_MODE(s, 0);
} else {
settings->spindle_mode[s] = CONSTANT_SURFACE;
if(block->d_flag)
enqueue_SET_SPINDLE_MODE(s, fabs(block->d_number_float));
else
enqueue_SET_SPINDLE_MODE(s, 1e30);
}
}
}
return INTERP_OK;
}
int Interp::convert_stop(block_pointer block, setup_pointer settings) {
int index;
char *line;
int length;
double cx, cy, cz;
comp_get_current(settings, &cx, &cy, &cz);
CHP(move_endpoint_and_flush(settings, cx, cy));
dequeue_canons(settings);
CHKS((block->m_modes[4] == 99 && settings->call_level > 0),
(_("Bug: Reached convert_stop() from M99 as subprogram return")));
if (block->m_modes[4] == 0) {
PROGRAM_STOP();
} else if (block->m_modes[4] == 60) {
PALLET_SHUTTLE();
PROGRAM_STOP();
} else if (block->m_modes[4] == 1) {
OPTIONAL_PROGRAM_STOP();
} else if (block->m_modes[4] == 99 && _setup.loop_on_main_m99) {
logDebug("M99 main program endless loop");
loop_to_beginning(settings); FINISH(); return INTERP_EXECUTE_FINISH; } else if ((block->m_modes[4] == 2) || (block->m_modes[4] == 30) ||
(block->m_modes[4] == 99 && !_setup.loop_on_main_m99)
) {
settings->current_x += settings->origin_offset_x;
settings->current_y += settings->origin_offset_y;
settings->current_z += settings->origin_offset_z;
settings->AA_current += settings->AA_origin_offset;
settings->BB_current += settings->BB_origin_offset;
settings->CC_current += settings->CC_origin_offset;
settings->u_current += settings->u_origin_offset;
settings->v_current += settings->v_origin_offset;
settings->w_current += settings->w_origin_offset;
rotate(&settings->current_x, &settings->current_y, settings->rotation_xy);
settings->origin_index = 1;
settings->parameters[5220] = 1.0;
settings->origin_offset_x = USER_TO_PROGRAM_LEN(settings->parameters[5221]);
settings->origin_offset_y = USER_TO_PROGRAM_LEN(settings->parameters[5222]);
settings->origin_offset_z = USER_TO_PROGRAM_LEN(settings->parameters[5223]);
settings->AA_origin_offset = USER_TO_PROGRAM_ANG(settings->parameters[5224]);
settings->BB_origin_offset = USER_TO_PROGRAM_ANG(settings->parameters[5225]);
settings->CC_origin_offset = USER_TO_PROGRAM_ANG(settings->parameters[5226]);
settings->u_origin_offset = USER_TO_PROGRAM_LEN(settings->parameters[5227]);
settings->v_origin_offset = USER_TO_PROGRAM_LEN(settings->parameters[5228]);
settings->w_origin_offset = USER_TO_PROGRAM_LEN(settings->parameters[5229]);
settings->rotation_xy = settings->parameters[5230];
rotate(&settings->current_x, &settings->current_y, -settings->rotation_xy);
settings->current_x -= settings->origin_offset_x;
settings->current_y -= settings->origin_offset_y;
settings->current_z -= settings->origin_offset_z;
settings->AA_current -= settings->AA_origin_offset;
settings->BB_current -= settings->BB_origin_offset;
settings->CC_current -= settings->CC_origin_offset;
settings->u_current -= settings->u_origin_offset;
settings->v_current -= settings->v_origin_offset;
settings->w_current -= settings->w_origin_offset;
SET_G5X_OFFSET(settings->origin_index,
settings->origin_offset_x,
settings->origin_offset_y,
settings->origin_offset_z,
settings->AA_origin_offset,
settings->BB_origin_offset,
settings->CC_origin_offset,
settings->u_origin_offset,
settings->v_origin_offset,
settings->w_origin_offset);
SET_XY_ROTATION(settings->rotation_xy);
if (settings->plane != CANON_PLANE_XY) {
SELECT_PLANE(CANON_PLANE_XY);
settings->plane = CANON_PLANE_XY;
}
settings->distance_mode = MODE_ABSOLUTE;
settings->feed_mode = UNITS_PER_MINUTE;
SET_FEED_MODE(0, 0);
settings->feed_rate = block->f_number;
SET_FEED_RATE(0);
if (!settings->feed_override) {
ENABLE_FEED_OVERRIDE();
settings->feed_override = true;
}
settings->cutter_comp_side = false;
settings->cutter_comp_firstmove = true;
for (int s = 0; s < settings->num_spindles; s++){
STOP_SPINDLE_TURNING(s);
settings->spindle_turning[s] = CANON_STOPPED;
settings->speed_override[s] = true;
SET_SPINDLE_MODE(s, 0);
}
settings->motion_mode = G_1;
if (settings->mist) {
MIST_OFF();
settings->mist = false;
}
if (settings->flood) {
FLOOD_OFF();
settings->flood = false;
}
if (settings->disable_g92_persistence)
for (index=5210; index<=5219; index++)
settings->parameters[index] = 0;
if (block->m_modes[4] == 30)
PALLET_SHUTTLE();
PROGRAM_END();
if (_setup.percent_flag && _setup.file_pointer) {
line = _setup.linetext;
for (;;) {
if (fgets(line, LINELEN, _setup.file_pointer) == NULL) {
enqueue_COMMENT("interpreter: percent sign missing from end of file");
break;
}
length = strlen(line);
if (length == (LINELEN - 1)) { for (; fgetc(_setup.file_pointer) != '\n' && !feof(_setup.file_pointer););
continue;
}
for (index = (length - 1); (index >= 0) && (isspace(line[index])); index--);
if (line[index] == '%') {
for (index--; (index >= 0) && (isspace(line[index])); index--);
if (index == -1) break;
}
}
}
unwind_call(INTERP_EXIT, __FILE__,__LINE__,__FUNCTION__);
return INTERP_EXIT;
} else
ERS(NCE_BUG_CODE_NOT_M0_M1_M2_M30_M60_M99);
return INTERP_OK;
}
int Interp::convert_straight(int move, block_pointer block, setup_pointer settings) {
double end_x;
double end_y;
double end_z;
double AA_end;
double BB_end;
double CC_end;
double u_end, v_end, w_end;
int status;
settings->arc_not_allowed = false;
if (move == G_1) {
if (settings->feed_mode == UNITS_PER_MINUTE) {
CHKS((settings->feed_rate == 0.0), NCE_CANNOT_DO_G1_WITH_ZERO_FEED_RATE);
} else if (settings->feed_mode == UNITS_PER_REVOLUTION) {
CHKS((settings->feed_rate == 0.0), NCE_CANNOT_DO_G1_WITH_ZERO_FEED_RATE);
CHKS((settings->speed[settings->active_spindle] == 0.0),
(_("Cannot feed with zero spindle speed in feed per rev mode")));
} else if (settings->feed_mode == INVERSE_TIME) {
CHKS((!block->f_flag),
NCE_F_WORD_MISSING_WITH_INVERSE_TIME_G1_MOVE);
}
}
settings->motion_mode = move;
CHP(find_ends(block, settings, &end_x, &end_y, &end_z,
&AA_end, &BB_end, &CC_end, &u_end, &v_end, &w_end));
if (move == G_1) {
inverse_time_rate_straight(end_x, end_y, end_z,
AA_end, BB_end, CC_end,
u_end, v_end, w_end,
block, settings);
}
if ((settings->cutter_comp_side) &&
(settings->cutter_comp_radius > 0.0)) {
CHKS((block->g_modes[GM_MODAL_0] == G_53),
NCE_CANNOT_USE_G53_WITH_CUTTER_RADIUS_COMP);
if(settings->plane == CANON_PLANE_XZ) {
if (settings->cutter_comp_firstmove)
status = convert_straight_comp1(move, block, settings, end_z, end_x, end_y,
AA_end, BB_end, CC_end, u_end, v_end, w_end);
else
status = convert_straight_comp2(move, block, settings, end_z, end_x, end_y,
AA_end, BB_end, CC_end, u_end, v_end, w_end);
} else if(settings->plane == CANON_PLANE_XY) {
if (settings->cutter_comp_firstmove)
status = convert_straight_comp1(move, block, settings, end_x, end_y, end_z,
AA_end, BB_end, CC_end, u_end, v_end, w_end);
else
status = convert_straight_comp2(move, block, settings, end_x, end_y, end_z,
AA_end, BB_end, CC_end, u_end, v_end, w_end);
} else ERS("BUG: Invalid plane for cutter compensation");
CHP(status);
} else if (move == G_0) {
STRAIGHT_TRAVERSE(block->line_number, end_x, end_y, end_z,
AA_end, BB_end, CC_end,
u_end, v_end, w_end);
settings->current_x = end_x;
settings->current_y = end_y;
settings->current_z = end_z;
} else if (move == G_1) {
STRAIGHT_FEED(block->line_number, end_x, end_y, end_z,
AA_end, BB_end, CC_end,
u_end, v_end, w_end);
settings->current_x = end_x;
settings->current_y = end_y;
settings->current_z = end_z;
} else if (move == G_33) {
if (block->dollar_flag){
CHKS((block->dollar_number < 0 || block->dollar_number >= settings->num_spindles),
(_("Invalid spindle ($) number in G33 move")));
settings->active_spindle = (int)block->dollar_number;
}
CHKS(((settings->spindle_turning[settings->active_spindle] != CANON_CLOCKWISE) &&
(settings->spindle_turning[settings->active_spindle] != CANON_COUNTERCLOCKWISE)),
_("Spindle not turning in G33"));
START_SPEED_FEED_SYNCH(settings->active_spindle, block->k_number, 0);
STRAIGHT_FEED(block->line_number, end_x, end_y, end_z, AA_end, BB_end, CC_end, u_end, v_end, w_end);
STOP_SPEED_FEED_SYNCH();
settings->current_x = end_x;
settings->current_y = end_y;
settings->current_z = end_z;
} else if (move == G_33_1) {
if (block->dollar_flag){
CHKS((block->dollar_number < 0 || block->dollar_number >= settings->num_spindles),
(_("Invalid spindle ($) number in G33.1 move")));
settings->active_spindle = (int)block->dollar_number;
}
CHKS(((settings->spindle_turning[settings->active_spindle] != CANON_CLOCKWISE) &&
(settings->spindle_turning[settings->active_spindle] != CANON_COUNTERCLOCKWISE)),
_("Spindle not turning in G33.1"));
START_SPEED_FEED_SYNCH(settings->active_spindle, block->k_number, 0);
double scale = 1;
if(block->i_flag){
scale = block->i_number;
if(scale < 1){
scale = 1;
}
}
RIGID_TAP(block->line_number, end_x, end_y, end_z, scale);
STOP_SPEED_FEED_SYNCH();
} else if (move == G_76) {
if (block->dollar_flag){
CHKS((block->dollar_number < 0 || block->dollar_number >= settings->num_spindles),
(_("Invalid D-number in G76 cycle")));
settings->active_spindle = (int)block->dollar_number;
}
CHKS(((settings->spindle_turning[settings->active_spindle] != CANON_CLOCKWISE) &&
(settings->spindle_turning[settings->active_spindle] != CANON_COUNTERCLOCKWISE)),
_("Chosen spindle (%i) not turning in G76"), settings->active_spindle);
CHKS((settings->AA_current != AA_end ||
settings->BB_current != BB_end ||
settings->CC_current != CC_end ||
settings->u_current != u_end ||
settings->v_current != v_end ||
settings->w_current != w_end), NCE_CANNOT_MOVE_ROTARY_AXES_WITH_G76);
int result = convert_threading_cycle(block, settings, end_x, end_y, end_z);
if(result != INTERP_OK) return result;
} else
ERS(NCE_BUG_CODE_NOT_G0_OR_G1);
settings->AA_current = AA_end;
settings->BB_current = BB_end;
settings->CC_current = CC_end;
settings->u_current = u_end;
settings->v_current = v_end;
settings->w_current = w_end;
return INTERP_OK;
}
int Interp::convert_straight_indexer(int axis, int jnum, block_pointer block, setup_pointer settings) {
double end_x, end_y, end_z;
double AA_end, BB_end, CC_end;
double u_end, v_end, w_end;
find_ends(block, settings, &end_x, &end_y, &end_z,
&AA_end, &BB_end, &CC_end, &u_end, &v_end, &w_end);
CHKS((end_x != settings->current_x ||
end_y != settings->current_y ||
end_z != settings->current_z ||
u_end != settings->u_current ||
v_end != settings->v_current ||
w_end != settings->w_current ||
(axis != 3 && AA_end != settings->AA_current) ||
(axis != 4 && BB_end != settings->BB_current) ||
(axis != 5 && CC_end != settings->CC_current)),
_("BUG: An axis incorrectly moved along with an indexer"));
switch(axis) {
case 3:
issue_straight_index(axis, jnum, AA_end, block->line_number, settings);
break;
case 4:
issue_straight_index(axis, jnum, BB_end, block->line_number, settings);
break;
case 5:
issue_straight_index(axis, jnum, CC_end, block->line_number, settings);
break;
default:
ERS((_("BUG: trying to index incorrect axis")));
}
return INTERP_OK;
}
int Interp::issue_straight_index(int axis, int jnum, double target, int lineno, setup_pointer settings) {
CANON_MOTION_MODE save_mode;
double save_tolerance;
save_mode = GET_EXTERNAL_MOTION_CONTROL_MODE();
save_tolerance = GET_EXTERNAL_MOTION_CONTROL_TOLERANCE();
if (save_mode != CANON_EXACT_PATH)
SET_MOTION_CONTROL_MODE(CANON_EXACT_PATH, 0);
double AA_end = axis == 3? target: settings->AA_current;
double BB_end = axis == 4? target: settings->BB_current;
double CC_end = axis == 5? target: settings->CC_current;
UNLOCK_ROTARY(lineno, jnum);
STRAIGHT_TRAVERSE(lineno, settings->current_x, settings->current_y, settings->current_z,
AA_end, BB_end, CC_end,
settings->u_current, settings->v_current, settings->w_current);
LOCK_ROTARY(lineno, jnum);
if(save_mode != CANON_EXACT_PATH)
SET_MOTION_CONTROL_MODE(save_mode, save_tolerance);
settings->AA_current = AA_end;
settings->BB_current = BB_end;
settings->CC_current = CC_end;
return INTERP_OK;
}
#define AABBCC settings->AA_current, settings->BB_current, settings->CC_current, settings->u_current, settings->v_current, settings->w_current
static void
threading_pass(setup_pointer settings, block_pointer block,
int boring, double safe_x, double depth, double end_depth,
double start_y, double start_z, double zoff, double taper_dist,
int entry_taper, int exit_taper, double taper_pitch,
double pitch, double full_threadheight, double target_z) {
STRAIGHT_TRAVERSE(block->line_number, boring?
safe_x + depth - end_depth:
safe_x - depth + end_depth,
start_y, start_z - zoff, AABBCC); if(taper_dist && entry_taper) {
DISABLE_FEED_OVERRIDE();
START_SPEED_FEED_SYNCH(settings->active_spindle, taper_pitch, 0);
STRAIGHT_FEED(block->line_number, boring?
safe_x + depth - full_threadheight:
safe_x - depth + full_threadheight,
start_y, start_z - zoff, AABBCC); STRAIGHT_FEED(block->line_number, boring? safe_x + depth: safe_x - depth, start_y, start_z - zoff - taper_dist, AABBCC);
START_SPEED_FEED_SYNCH(settings->active_spindle, pitch, 0);
} else {
STRAIGHT_TRAVERSE(block->line_number, boring? safe_x + depth: safe_x - depth,
start_y, start_z - zoff, AABBCC); DISABLE_FEED_OVERRIDE();
START_SPEED_FEED_SYNCH(settings->active_spindle, pitch, 0);
}
if(taper_dist && exit_taper) {
STRAIGHT_FEED(block->line_number, boring? safe_x + depth: safe_x - depth, start_y, target_z - zoff + taper_dist, AABBCC);
START_SPEED_FEED_SYNCH(settings->active_spindle, taper_pitch, 0);
STRAIGHT_FEED(block->line_number, boring?
safe_x + depth - full_threadheight:
safe_x - depth + full_threadheight,
start_y, target_z - zoff, AABBCC); } else {
STRAIGHT_FEED(block->line_number, boring? safe_x + depth: safe_x - depth,
start_y, target_z - zoff, AABBCC); }
STOP_SPEED_FEED_SYNCH();
STRAIGHT_TRAVERSE(block->line_number, boring?
safe_x + depth - end_depth:
safe_x - depth + end_depth,
start_y, target_z - zoff, AABBCC); ENABLE_FEED_OVERRIDE();
}
int Interp::convert_threading_cycle(block_pointer block,
setup_pointer settings,
double end_x, double end_y, double end_z) {
CHKS((settings->cutter_comp_side),
(_("Cannot use G76 threading cycle with cutter radius compensation on")));
CHKS((block->i_number == 0),
(_("In G76, I must not be 0")));
CHKS((block->j_number <= 0),
(_("In G76, J must be greater than 0")));
CHKS((block->k_number <= block->j_number),
(_("In G76, K must be greater than J")));
double start_x = settings->current_x;
double start_y = settings->current_y;
double start_z = settings->current_z;
double i_number = block->i_number;
double j_number = block->j_number;
double k_number = block->k_number;
if(_setup.lathe_diameter_mode){
i_number /= 2;
j_number /= 2;
k_number /= 2;
}
int boring = 0;
if (i_number > 0.0)
boring = 1;
double safe_x = start_x;
double full_dia_depth = fabs(i_number);
double start_depth = fabs(i_number) + fabs(j_number);
double cut_increment = fabs(j_number);
double full_threadheight = fabs(k_number);
double end_depth = fabs(k_number) + fabs(i_number);
double pitch = block->p_number;
double compound_angle = block->q_number;
if(compound_angle == -1) compound_angle = 0;
compound_angle *= M_PIl/180.0;
if(end_z > start_z) compound_angle = -compound_angle;
int spring_cuts = block->h_flag ? block->h_number: 0;
double degression = block->r_number;
if(degression < 1.0 || !block->r_flag) degression = 1.0;
double taper_dist = block->e_flag? block->e_number: 0.0;
if(taper_dist < 0.0) taper_dist = 0.0;
double taper_pitch = taper_dist > 0.0?
pitch * hypot(taper_dist, full_threadheight)/taper_dist: pitch;
if(end_z > start_z) taper_dist = -taper_dist;
int taper_flags = block->l_number;
if(taper_flags < 0) taper_flags = 0;
int entry_taper = taper_flags & 1;
int exit_taper = taper_flags & 2;
double depth, zoff;
int pass = 1;
double target_z = end_z + fabs(k_number) * tan(compound_angle);
depth = start_depth;
zoff = (depth - full_dia_depth) * tan(compound_angle);
while (depth < end_depth) {
threading_pass(settings, block, boring, safe_x, depth, end_depth, start_y,
start_z, zoff, taper_dist, entry_taper, exit_taper,
taper_pitch, pitch, full_threadheight, target_z);
depth = full_dia_depth + cut_increment * pow(++pass, 1.0/degression);
zoff = (depth - full_dia_depth) * tan(compound_angle);
}
depth = end_depth;
zoff = (depth - full_dia_depth) * tan(compound_angle);
for(int i = 0; i<spring_cuts+1; i++) {
threading_pass(settings, block, boring, safe_x, depth, end_depth, start_y,
start_z, zoff, taper_dist, entry_taper, exit_taper,
taper_pitch, pitch, full_threadheight, target_z);
}
STRAIGHT_TRAVERSE(block->line_number, end_x, end_y, end_z, AABBCC);
settings->current_x = end_x;
settings->current_y = end_y;
settings->current_z = end_z;
#undef AABBC
return INTERP_OK;
}
int Interp::convert_straight_comp1(int move, block_pointer block, setup_pointer settings, double px, double py, double pz, double AA_end, double BB_end, double CC_end, double u_end, double v_end, double w_end)
{
double alpha;
double distance;
double radius = settings->cutter_comp_radius;
double end_x, end_y;
int side = settings->cutter_comp_side;
double cx, cy, cz;
comp_get_current(settings, &cx, &cy, &cz);
distance = hypot((px - cx), (py - cy));
CHKS(((side != LEFT) && (side != RIGHT)), NCE_BUG_SIDE_NOT_RIGHT_OR_LEFT);
CHKS((distance <= radius), _("Length of cutter compensation entry move is not greater than the tool radius"));
alpha = atan2(py - cy, px - cx) + (side == LEFT ? M_PIl/2. : -M_PIl/2.);
end_x = (px + (radius * cos(alpha)));
end_y = (py + (radius * sin(alpha)));
set_endpoint(cx, cy);
if (move == G_0) {
enqueue_STRAIGHT_TRAVERSE(settings, block->line_number,
cos(alpha), sin(alpha), 0,
end_x, end_y, pz,
AA_end, BB_end, CC_end, u_end, v_end, w_end);
}
else if (move == G_1) {
enqueue_STRAIGHT_FEED(settings, block->line_number,
cos(alpha), sin(alpha), 0,
end_x, end_y, pz,
AA_end, BB_end, CC_end, u_end, v_end, w_end);
} else
ERS(NCE_BUG_CODE_NOT_G0_OR_G1);
settings->cutter_comp_firstmove = false;
comp_set_current(settings, end_x, end_y, pz);
settings->AA_current = AA_end;
settings->BB_current = BB_end;
settings->CC_current = CC_end;
settings->u_current = u_end;
settings->v_current = v_end;
settings->w_current = w_end;
comp_set_programmed(settings, px, py, pz);
return INTERP_OK;
}
int Interp::convert_straight_comp2(int move, block_pointer block, setup_pointer settings, double px, double py, double pz, double AA_end, double BB_end, double CC_end, double u_end, double v_end, double w_end)
{
double alpha;
double beta;
double end_x, end_y, end_z;
double gamma;
double mid_x, mid_y;
double radius;
int side;
double small = TOLERANCE_CONCAVE_CORNER;
double opx, opy, opz;
double theta;
double cx, cy, cz;
int concave;
comp_get_current(settings, &cx, &cy, &cz);
comp_get_current(settings, &end_x, &end_y, &end_z);
comp_get_programmed(settings, &opx, &opy, &opz);
if ((py == opy) && (px == opx)) {
if (move == G_0) {
enqueue_STRAIGHT_TRAVERSE(settings, block->line_number,
px - opx, py - opy, pz - opz,
cx, cy, pz,
AA_end, BB_end, CC_end, u_end, v_end, w_end);
} else if (move == G_1) {
enqueue_STRAIGHT_FEED(settings, block->line_number,
px - opx, py - opy, pz - opz,
cx, cy, pz, AA_end, BB_end, CC_end, u_end, v_end, w_end);
} else
ERS(NCE_BUG_CODE_NOT_G0_OR_G1);
} else {
side = settings->cutter_comp_side;
radius = settings->cutter_comp_radius;
theta = atan2(cy - opy, cx - opx);
alpha = atan2(py - opy, px - opx);
if (side == LEFT) {
if (theta < alpha)
theta = (theta + (2 * M_PIl));
beta = ((theta - alpha) - M_PI_2l);
gamma = M_PI_2l;
} else if (side == RIGHT) {
if (alpha < theta)
alpha = (alpha + (2 * M_PIl));
beta = ((alpha - theta) - M_PI_2l);
gamma = -M_PI_2l;
} else
ERS(NCE_BUG_SIDE_NOT_RIGHT_OR_LEFT);
end_x = (px + (radius * cos(alpha + gamma)));
end_y = (py + (radius * sin(alpha + gamma)));
mid_x = (opx + (radius * cos(alpha + gamma)));
mid_y = (opy + (radius * sin(alpha + gamma)));
if ((beta < -small) || (beta > (M_PIl + small))) {
concave = 1;
} else if (beta > (M_PIl - small) &&
(!qc().empty() && qc().front().type == QARC_FEED &&
((side == RIGHT && qc().front().data.arc_feed.turn > 0) ||
(side == LEFT && qc().front().data.arc_feed.turn < 0)))) {
concave = 1;
} else {
concave = 0;
mid_x = (opx + (radius * cos(alpha + gamma)));
mid_y = (opy + (radius * sin(alpha + gamma)));
}
if (!concave && (beta > small)) {
CHP(move_endpoint_and_flush(settings, cx, cy));
if(move == G_1) {
enqueue_ARC_FEED(settings, block->line_number,
0.0, mid_x, mid_y, opx, opy,
((side == LEFT) ? -1 : 1), cz,
AA_end, BB_end, CC_end, u_end, v_end, w_end);
dequeue_canons(settings);
set_endpoint(mid_x, mid_y);
} else if(move == G_0) {
enqueue_STRAIGHT_TRAVERSE(settings, block->line_number,
0.0, 0.0, 0.0,
mid_x, mid_y, cz,
AA_end, BB_end, CC_end,
u_end, v_end, w_end);
dequeue_canons(settings);
set_endpoint(mid_x, mid_y);
} else ERS(NCE_BUG_CODE_NOT_G0_OR_G1);
} else if (concave) {
if (qc().front().type != QARC_FEED) {
double retreat;
double halfcorner = (beta + M_PIl) / 2.0;
CHKS((halfcorner == 0.0), (_("Zero degree inside corner is invalid for cutter compensation")));
retreat = radius / tan(halfcorner);
mid_x = cx + retreat * cos(theta + gamma);
mid_y = cy + retreat * sin(theta + gamma);
CHP(move_endpoint_and_flush(settings, mid_x, mid_y));
} else {
arc_feed prev = qc().front().data.arc_feed;
double oldrad = hypot(prev.center2 - prev.end2, prev.center1 - prev.end1);
double oldrad_uncomp;
double base_dir = atan2(py - opy, px - opx);
double theta;
double phi;
theta = (prev.turn > 0) ? base_dir + M_PI_2l : base_dir - M_PI_2l;
phi = atan2(prev.center2 - opy, prev.center1 - opx);
if TOOL_INSIDE_ARC(side, prev.turn) {
oldrad_uncomp = oldrad + radius;
} else {
oldrad_uncomp = oldrad - radius;
}
double alpha = theta - phi;
double d = oldrad_uncomp * cos(alpha);
double d2;
double angle_from_center;
if TOOL_INSIDE_ARC(side, prev.turn) {
d2 = d - radius;
double l = d2/oldrad;
CHKS((l > 1.0 || l < -1.0), _("Arc to straight motion makes a corner the compensated tool can't fit in without gouging"));
if(prev.turn > 0)
angle_from_center = - acos(l) + theta + M_PIl;
else
angle_from_center = acos(l) + theta + M_PIl;
} else {
d2 = d + radius;
double l = d2/oldrad;
CHKS((l > 1.0 || l < -1.0), _("Arc to straight motion makes a corner the compensated tool can't fit in without gouging"));
if(prev.turn > 0)
angle_from_center = acos(l) + theta + M_PIl;
else
angle_from_center = - acos(l) + theta + M_PIl;
}
mid_x = prev.center1 + oldrad * cos(angle_from_center);
mid_y = prev.center2 + oldrad * sin(angle_from_center);
CHP(move_endpoint_and_flush(settings, mid_x, mid_y));
}
} else {
dequeue_canons(settings);
set_endpoint(cx, cy);
}
(move == G_0? enqueue_STRAIGHT_TRAVERSE: enqueue_STRAIGHT_FEED)
(settings, block->line_number,
px - opx, py - opy, pz - opz,
end_x, end_y, pz,
AA_end, BB_end, CC_end,
u_end, v_end, w_end);
}
comp_set_current(settings, end_x, end_y, pz);
settings->AA_current = AA_end;
settings->BB_current = BB_end;
settings->CC_current = CC_end;
settings->u_current = u_end;
settings->v_current = v_end;
settings->w_current = w_end;
comp_set_programmed(settings, px, py, pz);
return INTERP_OK;
}
int Interp::convert_tool_change(setup_pointer settings) {
if (settings->selected_pocket < 0) {
ERS(NCE_TXX_MISSING_FOR_M6);
}
CHKS((settings->cutter_comp_side),
(_("Cannot change tools with cutter radius compensation on")));
START_CHANGE(); if (!settings->tool_change_with_spindle_on) {
for (int s = 0; s < settings->num_spindles; s++){
STOP_SPINDLE_TURNING(s);
settings->spindle_turning[s] = CANON_STOPPED;
}
}
if (settings->tool_change_quill_up) {
double up_z;
double discard;
find_relative(0., 0., 0., 0., 0., 0., 0., 0., 0.,
&discard, &discard, &up_z,
&discard, &discard, &discard,
&discard, &discard, &discard,
settings);
COMMENT("AXIS,hide");
STRAIGHT_TRAVERSE(-1, settings->current_x, settings->current_y, up_z,
settings->AA_current, settings->BB_current, settings->CC_current,
settings->u_current, settings->v_current, settings->w_current);
COMMENT("AXIS,show");
settings->current_z = up_z;
}
if (settings->tool_change_at_g30) {
double end_x;
double end_y;
double end_z;
double AA_end;
double BB_end;
double CC_end;
double u_end;
double v_end;
double w_end;
find_relative(USER_TO_PROGRAM_LEN(settings->parameters[5181]),
USER_TO_PROGRAM_LEN(settings->parameters[5182]),
USER_TO_PROGRAM_LEN(settings->parameters[5183]),
USER_TO_PROGRAM_ANG(settings->parameters[5184]),
USER_TO_PROGRAM_ANG(settings->parameters[5185]),
USER_TO_PROGRAM_ANG(settings->parameters[5186]),
USER_TO_PROGRAM_LEN(settings->parameters[5187]),
USER_TO_PROGRAM_LEN(settings->parameters[5188]),
USER_TO_PROGRAM_LEN(settings->parameters[5189]),
&end_x, &end_y, &end_z,
&AA_end, &BB_end, &CC_end,
&u_end, &v_end, &w_end, settings);
COMMENT("AXIS,hide");
if (AA_end != settings->AA_current && (-1 != settings->a_indexer_jnum) )
issue_straight_index(3,settings->a_indexer_jnum, AA_end, -1, settings);
if (BB_end != settings->BB_current && (-1 != settings->b_indexer_jnum) )
issue_straight_index(4,settings->b_indexer_jnum, BB_end, -1, settings);
if (CC_end != settings->CC_current && (-1 != settings->c_indexer_jnum) )
issue_straight_index(5,settings->c_indexer_jnum, CC_end, -1, settings);
STRAIGHT_TRAVERSE(-1, end_x, end_y, end_z,
AA_end, BB_end, CC_end,
u_end, v_end, w_end);
COMMENT("AXIS,show");
settings->current_x = end_x;
settings->current_y = end_y;
settings->current_z = end_z;
settings->AA_current = AA_end;
settings->BB_current = BB_end;
settings->CC_current = CC_end;
settings->u_current = u_end;
settings->v_current = v_end;
settings->w_current = w_end;
}
CHANGE_TOOL(settings->selected_pocket);
settings->current_pocket = settings->selected_pocket;
settings->toolchange_flag = true;
set_tool_parameters();
return INTERP_OK;
}
int Interp::convert_tool_length_offset(int g_code, block_pointer block, setup_pointer settings) {
int pocket_number;
EmcPose tool_offset;
ZERO_EMC_POSE(tool_offset);
CHKS((settings->cutter_comp_side),
(_("Cannot change tool offset with cutter radius compensation on")));
if (g_code == G_49) {
pocket_number = 0;
} else if (g_code == G_43) {
logDebug("convert_tool_length_offset h_flag=%d h_number=%d toolchange_flag=%d current_pocket=%d\n",
block->h_flag,block->h_number,settings->toolchange_flag,settings->current_pocket);
if(block->h_flag) {
CHP((find_tool_pocket(settings, block->h_number, &pocket_number)));
} else if (settings->toolchange_flag) {
pocket_number = settings->current_pocket;
} else {
pocket_number = 0;
}
logDebug("convert_tool_length_offset: using index=%d spindle_toolno=%d pocket_toolno=%d",
pocket_number, settings->tool_table[0].toolno,settings->tool_table[settings->current_pocket].toolno);
tool_offset.tran.x = USER_TO_PROGRAM_LEN(settings->tool_table[pocket_number].offset.tran.x);
tool_offset.tran.y = USER_TO_PROGRAM_LEN(settings->tool_table[pocket_number].offset.tran.y);
tool_offset.tran.z = USER_TO_PROGRAM_LEN(settings->tool_table[pocket_number].offset.tran.z);
tool_offset.a = USER_TO_PROGRAM_ANG(settings->tool_table[pocket_number].offset.a);
tool_offset.b = USER_TO_PROGRAM_ANG(settings->tool_table[pocket_number].offset.b);
tool_offset.c = USER_TO_PROGRAM_ANG(settings->tool_table[pocket_number].offset.c);
tool_offset.u = USER_TO_PROGRAM_LEN(settings->tool_table[pocket_number].offset.u);
tool_offset.v = USER_TO_PROGRAM_LEN(settings->tool_table[pocket_number].offset.v);
tool_offset.w = USER_TO_PROGRAM_LEN(settings->tool_table[pocket_number].offset.w);
} else if (g_code == G_43_1) {
tool_offset = settings->tool_offset;
pocket_number = -1;
if(block->x_flag) tool_offset.tran.x = block->x_number;
if(block->y_flag) tool_offset.tran.y = block->y_number;
if(block->z_flag) tool_offset.tran.z = block->z_number;
if(block->a_flag) tool_offset.a = block->a_number;
if(block->b_flag) tool_offset.b = block->b_number;
if(block->c_flag) tool_offset.c = block->c_number;
if(block->u_flag) tool_offset.u = block->u_number;
if(block->v_flag) tool_offset.v = block->v_number;
if(block->w_flag) tool_offset.w = block->w_number;
} else if (g_code == G_43_2) {
CHKS((!block->h_flag), (_("G43.2: H-word missing")));
CHP((find_tool_pocket(settings, block->h_number, &pocket_number)));
tool_offset = settings->tool_offset;
tool_offset.tran.x += USER_TO_PROGRAM_LEN(settings->tool_table[pocket_number].offset.tran.x);
tool_offset.tran.y += USER_TO_PROGRAM_LEN(settings->tool_table[pocket_number].offset.tran.y);
tool_offset.tran.z += USER_TO_PROGRAM_LEN(settings->tool_table[pocket_number].offset.tran.z);
tool_offset.a += USER_TO_PROGRAM_ANG(settings->tool_table[pocket_number].offset.a);
tool_offset.b += USER_TO_PROGRAM_ANG(settings->tool_table[pocket_number].offset.b);
tool_offset.c += USER_TO_PROGRAM_ANG(settings->tool_table[pocket_number].offset.c);
tool_offset.u += USER_TO_PROGRAM_LEN(settings->tool_table[pocket_number].offset.u);
tool_offset.v += USER_TO_PROGRAM_LEN(settings->tool_table[pocket_number].offset.v);
tool_offset.w += USER_TO_PROGRAM_LEN(settings->tool_table[pocket_number].offset.w);
} else {
ERS("BUG: Code not G43, G43.1, G43.2, or G49");
}
USE_TOOL_LENGTH_OFFSET(tool_offset);
double dx, dy;
dx = settings->tool_offset.tran.x - tool_offset.tran.x;
dy = settings->tool_offset.tran.y - tool_offset.tran.y;
rotate(&dx, &dy, -settings->rotation_xy);
settings->current_x += dx;
settings->current_y += dy;
settings->current_z += settings->tool_offset.tran.z - tool_offset.tran.z;
settings->AA_current += settings->tool_offset.a - tool_offset.a;
settings->BB_current += settings->tool_offset.b - tool_offset.b;
settings->CC_current += settings->tool_offset.c - tool_offset.c;
settings->u_current += settings->tool_offset.u - tool_offset.u;
settings->v_current += settings->tool_offset.v - tool_offset.v;
settings->w_current += settings->tool_offset.w - tool_offset.w;
settings->tool_offset = tool_offset;
return INTERP_OK;
}
int Interp::convert_tool_select(block_pointer block, setup_pointer settings) {
int pocket;
CHP((find_tool_pocket(settings, block->t_number, &pocket)));
SELECT_POCKET(pocket, block->t_number);
settings->selected_pocket = pocket;
settings->selected_tool = block->t_number;
return INTERP_OK;
}