#include <float.h>
#include "posemath.h"
#include "rtapi.h"
#include "hal.h"
#include "motion.h"
#include "motion_debug.h"
#include "motion_struct.h"
#include "mot_priv.h"
#include "rtapi_math.h"
#include "motion_types.h"
#include "homing.h"
#include "tp_debug.h"
#define ABS(x) (((x) < 0) ? -(x) : (x))
#define _(s) (s)
extern int motion_num_spindles;
static int rehomeAll;
bool checkAllHomed(void)
{
int joint_num;
emcmot_joint_t *joint;
for (joint_num = 0; joint_num < ALL_JOINTS; joint_num++) {
joint = &joints[joint_num];
if (!GET_JOINT_ACTIVE_FLAG(joint)) {
continue;
}
if (!get_homed(joint_num) ) {
return 0;
}
}
return 1;
}
STATIC int limits_ok(void)
{
int joint_num;
emcmot_joint_t *joint;
for (joint_num = 0; joint_num < ALL_JOINTS; joint_num++) {
joint = &joints[joint_num];
if (!GET_JOINT_ACTIVE_FLAG(joint)) {
continue;
}
if (GET_JOINT_PHL_FLAG(joint) || GET_JOINT_NHL_FLAG(joint)) {
return 0;
}
}
return 1;
}
STATIC int joint_jog_ok(int joint_num, double vel)
{
emcmot_joint_t *joint;
int neg_limit_override, pos_limit_override;
joint = &joints[joint_num];
neg_limit_override = emcmotStatus->overrideLimitMask & ( 1 << (joint_num*2));
pos_limit_override = emcmotStatus->overrideLimitMask & ( 2 << (joint_num*2));
if ( neg_limit_override && pos_limit_override ) {
return 1;
}
if (joint_num < 0 || joint_num >= ALL_JOINTS) {
reportError(_("Can't jog invalid joint number %d."), joint_num);
return 0;
}
if (vel > 0.0 && GET_JOINT_PHL_FLAG(joint)) {
reportError(_("Can't jog joint %d further past max hard limit."),
joint_num);
return 0;
}
if (vel < 0.0 && GET_JOINT_NHL_FLAG(joint)) {
reportError(_("Can't jog joint %d further past min hard limit."),
joint_num);
return 0;
}
refresh_jog_limits(joint,joint_num);
if ( vel > 0.0 && (joint->pos_cmd > joint->max_jog_limit) ) {
reportError(_("Can't jog joint %d further past max soft limit."),
joint_num);
return 0;
}
if ( vel < 0.0 && (joint->pos_cmd < joint->min_jog_limit) ) {
reportError(_("Can't jog joint %d further past min soft limit."),
joint_num);
return 0;
}
return 1;
}
void refresh_jog_limits(emcmot_joint_t *joint, int joint_num)
{
double range;
if (get_homed(joint_num) ) {
joint->max_jog_limit = joint->max_pos_limit;
joint->min_jog_limit = joint->min_pos_limit;
} else {
range = joint->max_pos_limit - joint->min_pos_limit;
joint->max_jog_limit = joint->pos_fb + range;
joint->min_jog_limit = joint->pos_fb - range;
}
}
static int check_axis_constraint(double target, int id, char *move_type,
int axis_no, char axis_name) {
int in_range = 1;
double nl = axes[axis_no].min_pos_limit;
double pl = axes[axis_no].max_pos_limit;
double eps = 1e-308;
if ( (fabs(target) < eps)
&& (fabs(axes[axis_no].min_pos_limit) < eps)
&& (fabs(axes[axis_no].max_pos_limit) < eps) ) { return 1;}
if(target < nl) {
in_range = 0;
reportError(_("%s move on line %d would exceed %c's %s limit"),
move_type, id, axis_name, _("negative"));
}
if(target > pl) {
in_range = 0;
reportError(_("%s move on line %d would exceed %c's %s limit"),
move_type, id, axis_name, _("positive"));
}
return in_range;
}
STATIC int inRange(EmcPose pos, int id, char *move_type)
{
double joint_pos[EMCMOT_MAX_JOINTS];
int joint_num;
emcmot_joint_t *joint;
int in_range = 1;
if(check_axis_constraint(pos.tran.x, id, move_type, 0, 'X') == 0)
in_range = 0;
if(check_axis_constraint(pos.tran.y, id, move_type, 1, 'Y') == 0)
in_range = 0;
if(check_axis_constraint(pos.tran.z, id, move_type, 2, 'Z') == 0)
in_range = 0;
if(check_axis_constraint(pos.a, id, move_type, 3, 'A') == 0)
in_range = 0;
if(check_axis_constraint(pos.b, id, move_type, 4, 'B') == 0)
in_range = 0;
if(check_axis_constraint(pos.c, id, move_type, 5, 'C') == 0)
in_range = 0;
if(check_axis_constraint(pos.u, id, move_type, 6, 'U') == 0)
in_range = 0;
if(check_axis_constraint(pos.v, id, move_type, 7, 'V') == 0)
in_range = 0;
if(check_axis_constraint(pos.w, id, move_type, 8, 'W') == 0)
in_range = 0;
for (joint_num = 0; joint_num < ALL_JOINTS; joint_num++) {
joint_pos[joint_num] = 0.0;
}
if (kinematicsInverse(&pos, joint_pos, &iflags, &fflags) < 0)
{
reportError(_("%s move on line %d fails kinematicsInverse"),
move_type, id);
return 0;
}
for (joint_num = 0; joint_num < ALL_JOINTS; joint_num++) {
joint = &joints[joint_num];
if (!GET_JOINT_ACTIVE_FLAG(joint)) {
continue;
}
if(!isfinite(joint_pos[joint_num]))
{
reportError(_("%s move on line %d gave non-finite joint location on joint %d"),
move_type, id, joint_num);
in_range = 0;
continue;
}
if (joint_pos[joint_num] > joint->max_pos_limit) {
in_range = 0;
reportError(_("%s move on line %d would exceed joint %d's positive limit"),
move_type, id, joint_num);
}
if (joint_pos[joint_num] < joint->min_pos_limit) {
in_range = 0;
reportError(_("%s move on line %d would exceed joint %d's negative limit"),
move_type, id, joint_num);
}
}
return in_range;
}
void clearHomes(int joint_num)
{
int n;
if (emcmotConfig->kinType == KINEMATICS_INVERSE_ONLY) {
if (rehomeAll) {
for (n = 0; n < ALL_JOINTS; n++) {
set_joint_homed(joint_num,0);
}
} else {
set_joint_homed(joint_num,0);
}
}
}
void emcmotSetRotaryUnlock(int jnum, int unlock) {
if (NULL == emcmot_hal_data->joint[jnum].unlock) {
reportError(
"emcmotSetRotaryUnlock(): No unlock pin configured for joint %d\n"
" Use motmod parameter: unlock_joints_mask=%X",
jnum,1<<jnum);
return;
}
*(emcmot_hal_data->joint[jnum].unlock) = unlock;
}
int emcmotGetRotaryIsUnlocked(int jnum) {
static int gave_message = 0;
if (NULL == emcmot_hal_data->joint[jnum].unlock) {
if (!gave_message) {
reportError(
"emcmotGetRotaryUnlocked(): No unlock pin configured for joint %d\n"
" Use motmod parameter: unlock_joints_mask=%X'",
jnum,1<<jnum);
}
gave_message = 1;
return 0;
}
return *(emcmot_hal_data->joint[jnum].is_unlocked);
}
void emcmotDioWrite(int index, char value)
{
if ((index >= emcmotConfig->numDIO) || (index < 0)) {
rtapi_print_msg(RTAPI_MSG_ERR, "ERROR: index out of range, %d not in [0..%d] (increase num_dio/EMCMOT_MAX_DIO=%d)\n", index, emcmotConfig->numDIO, EMCMOT_MAX_DIO);
} else {
if (value != 0) {
*(emcmot_hal_data->synch_do[index])=1;
} else {
*(emcmot_hal_data->synch_do[index])=0;
}
}
}
void emcmotAioWrite(int index, double value)
{
if ((index >= emcmotConfig->numAIO) || (index < 0)) {
rtapi_print_msg(RTAPI_MSG_ERR, "ERROR: index out of range, %d not in [0..%d] (increase num_aio/EMCMOT_MAX_AIO=%d)\n", index, emcmotConfig->numAIO, EMCMOT_MAX_AIO);
} else {
*(emcmot_hal_data->analog_output[index]) = value;
}
}
STATIC int is_feed_type(int motion_type)
{
switch(motion_type) {
case EMC_MOTION_TYPE_ARC:
case EMC_MOTION_TYPE_FEED:
case EMC_MOTION_TYPE_PROBING:
return 1;
default:
rtapi_print_msg(RTAPI_MSG_ERR, "Internal error: unhandled motion type %d\n", motion_type);
case EMC_MOTION_TYPE_TOOLCHANGE:
case EMC_MOTION_TYPE_TRAVERSE:
case EMC_MOTION_TYPE_INDEXROTARY:
return 0;
}
}
void emcmotCommandHandler(void *arg, long period)
{
int joint_num, axis_num, spindle_num;
int n;
emcmot_joint_t *joint;
emcmot_axis_t *axis;
double tmp1;
emcmot_comp_entry_t *comp_entry;
char issue_atspeed = 0;
int abort = 0;
char* emsg = "";
if (emcmotCommand->head != emcmotCommand->tail) {
emcmotDebug->split++;
return;
}
if (emcmotCommand->commandNum != emcmotStatus->commandNumEcho) {
emcmotStatus->head++;
emcmotDebug->head++;
emcmotStatus->commandEcho = emcmotCommand->command;
emcmotStatus->commandNumEcho = emcmotCommand->commandNum;
emcmotStatus->commandStatus = EMCMOT_COMMAND_OK;
joint = 0;
axis = 0;
joint_num = emcmotCommand->joint;
axis_num = emcmotCommand->axis;
if ( emcmotCommand->command == EMCMOT_JOG_CONT
|| emcmotCommand->command == EMCMOT_JOG_INCR
|| emcmotCommand->command == EMCMOT_JOG_ABS
) {
if (GET_MOTION_TELEOP_FLAG() && axis_num < 0) {
emsg = "command.com teleop: unexpected negative axis_num";
if (joint_num >= 0) {
emsg = "Mode is TELEOP, cannot jog joint";
}
abort = 1;
}
if (!GET_MOTION_TELEOP_FLAG() && joint_num < 0) {
emsg = "command.com !teleop: unexpected negative joint_num";
if (axis_num >= 0) {
emsg = "Mode is NOT TELEOP, cannot jog axis coordinate";
}
abort = 1;
}
if ( !GET_MOTION_TELEOP_FLAG()
&& (joint_num >= ALL_JOINTS || joint_num < 0)
) {
rtapi_print_msg(RTAPI_MSG_ERR,
"Joint jog requested for undefined joint number=%d (min=0,max=%d)",
joint_num,ALL_JOINTS-1);
return;
}
if (GET_MOTION_TELEOP_FLAG()) {
axis = &axes[axis_num];
if ( (axis_num >= 0) && (axis->locking_joint >= 0) ) {
rtapi_print_msg(RTAPI_MSG_ERR,
"Cannot jog a locking indexer AXIS_%c,joint_num=%d\n",
"XYZABCUVW"[axis_num],axis->locking_joint);
return;
}
}
}
if (abort) {
switch (emcmotCommand->command) {
case EMCMOT_JOG_CONT:
rtapi_print_msg(RTAPI_MSG_ERR,"JOG_CONT %s\n",emsg);
break;
case EMCMOT_JOG_INCR:
rtapi_print_msg(RTAPI_MSG_ERR,"JOG_INCR %s\n",emsg);
break;
case EMCMOT_JOG_ABS:
rtapi_print_msg(RTAPI_MSG_ERR,"JOG_ABS %s\n",emsg);
break;
default: break;
}
return;
}
if (joint_num >= 0 && joint_num < ALL_JOINTS) {
joint = &joints[joint_num];
if ( ( emcmotCommand->command == EMCMOT_JOG_CONT
|| emcmotCommand->command == EMCMOT_JOG_INCR
|| emcmotCommand->command == EMCMOT_JOG_ABS
)
&& !(GET_MOTION_TELEOP_FLAG())
&& get_home_is_synchronized(joint_num)
&& !get_homing_is_active()
) {
if (emcmotConfig->kinType == KINEMATICS_IDENTITY) {
rtapi_print_msg(RTAPI_MSG_ERR,
"Homing is REQUIRED to jog requested coordinate\n"
"because joint (%d) home_sequence is synchronized (%d)\n"
,joint_num,get_home_sequence(joint_num));
} else {
rtapi_print_msg(RTAPI_MSG_ERR,
"Cannot jog joint %d because home_sequence is synchronized (%d)\n"
,joint_num,get_home_sequence(joint_num));
}
return;
}
}
if (axis_num >= 0 && axis_num < EMCMOT_MAX_AXIS) {
axis = &axes[axis_num];
}
switch (emcmotCommand->command) {
case EMCMOT_ABORT:
rtapi_print_msg(RTAPI_MSG_DBG, "ABORT");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
if (GET_MOTION_TELEOP_FLAG()) {
for (axis_num = 0; axis_num < EMCMOT_MAX_AXIS; axis_num++) {
axis = &axes[axis_num];
axis->teleop_tp.enable = 0;
}
} else if (GET_MOTION_COORD_FLAG()) {
tpAbort(&emcmotDebug->coord_tp);
} else {
for (joint_num = 0; joint_num < ALL_JOINTS; joint_num++) {
joint = &joints[joint_num];
joint->free_tp.enable = 0;
if ( ! get_home_is_idle(joint_num)) {
set_home_abort(joint_num);
}
}
}
SET_MOTION_ERROR_FLAG(0);
for (joint_num = 0; joint_num < ALL_JOINTS; joint_num++) {
joint = &joints[joint_num];
SET_JOINT_ERROR_FLAG(joint, 0);
SET_JOINT_FAULT_FLAG(joint, 0);
}
emcmotStatus->paused = 0;
break;
case EMCMOT_JOINT_ABORT:
rtapi_print_msg(RTAPI_MSG_DBG, "JOINT_ABORT");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
if (GET_MOTION_TELEOP_FLAG()) {
if (axis != 0) axis->teleop_tp.enable = 0;
} else if (GET_MOTION_COORD_FLAG()) {
} else {
if (joint != 0) joint->free_tp.enable = 0;
if (joint == 0) { break; }
if ( !get_home_is_idle(joint_num) ) {
set_home_abort(joint_num);
}
SET_JOINT_ERROR_FLAG(joint, 0);
}
break;
case EMCMOT_FREE:
for (axis_num = 0; axis_num < EMCMOT_MAX_AXIS; axis_num++) {
axis = &axes[axis_num];
if (axis != 0) { axis->teleop_tp.enable = 0; }
}
rtapi_print_msg(RTAPI_MSG_DBG, "FREE");
emcmotDebug->coordinating = 0;
emcmotDebug->teleoperating = 0;
break;
case EMCMOT_COORD:
rtapi_print_msg(RTAPI_MSG_DBG, "COORD");
emcmotDebug->coordinating = 1;
emcmotDebug->teleoperating = 0;
if (emcmotConfig->kinType != KINEMATICS_IDENTITY) {
if (!checkAllHomed()) {
reportError
(_("all joints must be homed before going into coordinated mode"));
emcmotDebug->coordinating = 0;
break;
}
}
break;
case EMCMOT_TELEOP:
rtapi_print_msg(RTAPI_MSG_DBG, "TELEOP");
switch_to_teleop_mode();
break;
case EMCMOT_SET_NUM_JOINTS:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_NUM_JOINTS");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", emcmotCommand->joint);
if (( emcmotCommand->joint <= 0 ) ||
( emcmotCommand->joint > EMCMOT_MAX_JOINTS )) {
break;
}
ALL_JOINTS = emcmotCommand->joint;
break;
case EMCMOT_SET_NUM_SPINDLES:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_NUM_SPINDLES");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", emcmotCommand->spindle);
if ( emcmotCommand->spindle > motion_num_spindles
|| emcmotCommand->spindle <= 0
|| emcmotCommand->spindle > EMCMOT_MAX_SPINDLES
) {
reportError("Problem:\n"
" motmod configured for %d spindles\n"
" but command requests %d spindles\n"
" Using: %d spindles",
motion_num_spindles,
emcmotCommand->spindle,
motion_num_spindles
);
emcmotConfig->numSpindles = motion_num_spindles;
} else {
emcmotConfig->numSpindles = emcmotCommand->spindle;
}
break;
case EMCMOT_SET_WORLD_HOME:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_WORLD_HOME");
emcmotStatus->world_home = emcmotCommand->pos;
break;
case EMCMOT_SET_JOINT_HOMING_PARAMS:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_JOINT_HOMING_PARAMS");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
emcmot_config_change();
if (joint == 0) {
break;
}
set_joint_homing_params(joint_num,
emcmotCommand->offset,
emcmotCommand->home,
emcmotCommand->home_final_vel,
emcmotCommand->search_vel,
emcmotCommand->latch_vel,
emcmotCommand->flags,
emcmotCommand->home_sequence,
emcmotCommand->volatile_home
);
break;
case EMCMOT_UPDATE_JOINT_HOMING_PARAMS:
rtapi_print_msg(RTAPI_MSG_DBG, "UPDATE_JOINT_HOMING_PARAMS");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
emcmot_config_change();
if (joint == 0) {
break;
}
update_joint_homing_params(joint_num,
emcmotCommand->offset,
emcmotCommand->home,
emcmotCommand->home_sequence
);
break;
case EMCMOT_OVERRIDE_LIMITS:
rtapi_print_msg(RTAPI_MSG_DBG, "OVERRIDE_LIMITS");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
if (joint_num < 0) {
rtapi_print_msg(RTAPI_MSG_DBG, "override off");
emcmotStatus->overrideLimitMask = 0;
} else {
rtapi_print_msg(RTAPI_MSG_DBG, "override on");
emcmotStatus->overrideLimitMask = 0;
for (joint_num = 0; joint_num < ALL_JOINTS; joint_num++) {
joint = &joints[joint_num];
if ( GET_JOINT_NHL_FLAG(joint) ) {
emcmotStatus->overrideLimitMask |= (1 << (joint_num*2));
}
if ( GET_JOINT_PHL_FLAG(joint) ) {
emcmotStatus->overrideLimitMask |= (2 << (joint_num*2));
}
}
}
emcmotDebug->overriding = 0;
for (joint_num = 0; joint_num < ALL_JOINTS; joint_num++) {
joint = &joints[joint_num];
SET_JOINT_ERROR_FLAG(joint, 0);
}
break;
case EMCMOT_SET_JOINT_MOTOR_OFFSET:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_JOINT_MOTOR_OFFSET");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
if(joint == 0) {
break;
}
joint->motor_offset = emcmotCommand->motor_offset;
break;
case EMCMOT_SET_JOINT_POSITION_LIMITS:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_JOINT_POSITION_LIMITS");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
emcmot_config_change();
if (joint == 0) {
break;
}
joint->min_pos_limit = emcmotCommand->minLimit;
joint->max_pos_limit = emcmotCommand->maxLimit;
break;
case EMCMOT_SET_JOINT_BACKLASH:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_JOINT_BACKLASH");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
emcmot_config_change();
if (joint == 0) {
break;
}
joint->backlash = emcmotCommand->backlash;
break;
case EMCMOT_SET_JOINT_MAX_FERROR:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_JOINT_MAX_FERROR");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
emcmot_config_change();
if (joint == 0 || emcmotCommand->maxFerror < 0.0) {
break;
}
joint->max_ferror = emcmotCommand->maxFerror;
break;
case EMCMOT_SET_JOINT_MIN_FERROR:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_JOINT_MIN_FERROR");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
emcmot_config_change();
if (joint == 0 || emcmotCommand->minFerror < 0.0) {
break;
}
joint->min_ferror = emcmotCommand->minFerror;
break;
case EMCMOT_JOG_CONT:
rtapi_print_msg(RTAPI_MSG_DBG, "JOG_CONT");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
if (!GET_MOTION_ENABLE_FLAG()) {
reportError(_("Can't jog joint when not enabled."));
SET_JOINT_ERROR_FLAG(joint, 1);
break;
}
if ( get_homing_is_active() ) {
reportError(_("Can't jog any joints while homing."));
SET_JOINT_ERROR_FLAG(joint, 1);
break;
}
if (emcmotStatus->net_feed_scale < 0.0001) {
break;
}
if (!GET_MOTION_TELEOP_FLAG()) {
if (joint->wheel_jjog_active) {
break;
}
if (get_home_needs_unlock_first(joint_num) ) {
reportError("Can't jog locking joint_num=%d",joint_num);
SET_JOINT_ERROR_FLAG(joint, 1);
break;
}
if (!joint_jog_ok(joint_num, emcmotCommand->vel)) {
SET_JOINT_ERROR_FLAG(joint, 1);
break;
}
refresh_jog_limits(joint,joint_num);
if (emcmotCommand->vel > 0.0) {
joint->free_tp.pos_cmd = joint->max_jog_limit;
} else {
joint->free_tp.pos_cmd = joint->min_jog_limit;
}
joint->free_tp.max_vel = fabs(emcmotCommand->vel);
joint->free_tp.max_acc = joint->acc_limit;
joint->kb_jjog_active = 1;
joint->free_tp.enable = 1;
for (axis_num = 0; axis_num < EMCMOT_MAX_AXIS; axis_num++) {
axis = &axes[axis_num];
if (axis != 0) { axis->teleop_tp.enable = 0; }
}
SET_JOINT_ERROR_FLAG(joint, 0);
clearHomes(joint_num);
} else {
if (GET_MOTION_ERROR_FLAG()) { break; }
axis_hal_t *axis_data = &(emcmot_hal_data->axis[axis_num]);
if ( axis->ext_offset_tp.enable
&& (fabs(*(axis_data->external_offset)) > EOFFSET_EPSILON)) {
if (emcmotCommand->vel > 0.0) {
axis->teleop_tp.pos_cmd = 1e12; } else {
axis->teleop_tp.pos_cmd = -1e12; }
} else {
if (emcmotCommand->vel > 0.0) {
axis->teleop_tp.pos_cmd = axis->max_pos_limit;
} else {
axis->teleop_tp.pos_cmd = axis->min_pos_limit;
}
}
axis->teleop_tp.max_vel = fabs(emcmotCommand->vel);
axis->teleop_tp.max_acc = axis->acc_limit;
axis->kb_ajog_active = 1;
for (joint_num = 0; joint_num < ALL_JOINTS; joint_num++) {
joint = &joints[joint_num];
if (joint != 0) { joint->free_tp.enable = 0; }
}
axis->teleop_tp.enable = 1;
}
break;
case EMCMOT_JOG_INCR:
rtapi_print_msg(RTAPI_MSG_DBG, "JOG_INCR");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
if (!GET_MOTION_ENABLE_FLAG()) {
reportError(_("Can't jog joint when not enabled."));
SET_JOINT_ERROR_FLAG(joint, 1);
break;
}
if ( get_homing_is_active() ) {
reportError(_("Can't jog any joint while homing."));
SET_JOINT_ERROR_FLAG(joint, 1);
break;
}
if (emcmotStatus->net_feed_scale < 0.0001 ) {
break;
}
if (!GET_MOTION_TELEOP_FLAG()) {
if (joint->wheel_jjog_active) {
break;
}
if (get_home_needs_unlock_first(joint_num) ) {
reportError("Can't jog locking joint_num=%d",joint_num);
SET_JOINT_ERROR_FLAG(joint, 1);
break;
}
if (!joint_jog_ok(joint_num, emcmotCommand->vel)) {
SET_JOINT_ERROR_FLAG(joint, 1);
break;
}
if (emcmotCommand->vel > 0.0) {
tmp1 = joint->free_tp.pos_cmd + emcmotCommand->offset;
} else {
tmp1 = joint->free_tp.pos_cmd - emcmotCommand->offset;
}
refresh_jog_limits(joint,joint_num);
if (tmp1 > joint->max_jog_limit) {
break;
}
if (tmp1 < joint->min_jog_limit) {
break;
}
joint->free_tp.pos_cmd = tmp1;
joint->free_tp.max_vel = fabs(emcmotCommand->vel);
joint->free_tp.max_acc = joint->acc_limit;
joint->kb_jjog_active = 1;
joint->free_tp.enable = 1;
for (axis_num = 0; axis_num < EMCMOT_MAX_AXIS; axis_num++) {
axis = &axes[axis_num];
if (axis != 0) { axis->teleop_tp.enable = 0; }
}
SET_JOINT_ERROR_FLAG(joint, 0);
clearHomes(joint_num);
} else {
if (GET_MOTION_ERROR_FLAG()) { break; }
if (emcmotCommand->vel > 0.0) {
tmp1 = axis->teleop_tp.pos_cmd + emcmotCommand->offset;
} else {
tmp1 = axis->teleop_tp.pos_cmd - emcmotCommand->offset;
}
axis_hal_t *axis_data = &(emcmot_hal_data->axis[axis_num]);
if ( axis->ext_offset_tp.enable
&& (fabs(*(axis_data->external_offset)) > EOFFSET_EPSILON)) {
} else {
if (tmp1 > axis->max_pos_limit) { break; }
if (tmp1 < axis->min_pos_limit) { break; }
}
axis->teleop_tp.pos_cmd = tmp1;
axis->teleop_tp.max_vel = fabs(emcmotCommand->vel);
axis->teleop_tp.max_acc = axis->acc_limit;
axis->kb_ajog_active = 1;
axis->teleop_tp.enable = 1;
for (joint_num = 0; joint_num < ALL_JOINTS; joint_num++) {
joint = &joints[joint_num];
if (joint != 0) { joint->free_tp.enable = 0; }
}
}
break;
case EMCMOT_JOG_ABS:
rtapi_print_msg(RTAPI_MSG_DBG, "JOG_ABS");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
if (joint == 0) {
break;
}
if (!GET_MOTION_ENABLE_FLAG()) {
reportError(_("Can't jog joint when not enabled."));
SET_JOINT_ERROR_FLAG(joint, 1);
break;
}
if ( get_homing_is_active() ) {
reportError(_("Can't jog any joints while homing."));
SET_JOINT_ERROR_FLAG(joint, 1);
break;
}
if (!GET_MOTION_TELEOP_FLAG()) {
if (joint->wheel_jjog_active) {
break;
}
if (emcmotStatus->net_feed_scale < 0.0001 ) {
break;
}
if (!joint_jog_ok(joint_num, emcmotCommand->vel)) {
SET_JOINT_ERROR_FLAG(joint, 1);
break;
}
joint->free_tp.pos_cmd = emcmotCommand->offset;
refresh_jog_limits(joint,joint_num);
if (joint->free_tp.pos_cmd > joint->max_jog_limit) {
joint->free_tp.pos_cmd = joint->max_jog_limit;
}
if (joint->free_tp.pos_cmd < joint->min_jog_limit) {
joint->free_tp.pos_cmd = joint->min_jog_limit;
}
joint->free_tp.max_vel = fabs(emcmotCommand->vel);
joint->free_tp.max_acc = joint->acc_limit;
joint->kb_jjog_active = 1;
joint->free_tp.enable = 1;
SET_JOINT_ERROR_FLAG(joint, 0);
clearHomes(joint_num);
} else {
axis->kb_ajog_active = 1;
if (axis->wheel_ajog_active) { break; }
if (emcmotCommand->vel > 0.0) {
tmp1 = axis->teleop_tp.pos_cmd + emcmotCommand->offset;
} else {
tmp1 = axis->teleop_tp.pos_cmd - emcmotCommand->offset;
}
if (tmp1 > axis->max_pos_limit) { break; }
if (tmp1 < axis->min_pos_limit) { break; }
axis->teleop_tp.pos_cmd = tmp1;
axis->teleop_tp.max_vel = fabs(emcmotCommand->vel);
axis->teleop_tp.max_acc = axis->acc_limit;
axis->kb_ajog_active = 1;
axis->teleop_tp.enable = 1;
for (joint_num = 0; joint_num < ALL_JOINTS; joint_num++) {
joint = &joints[joint_num];
if (joint != 0) { joint->free_tp.enable = 0; }
}
return;
}
break;
case EMCMOT_SET_TERM_COND:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_TERM_COND");
tpSetTermCond(&emcmotDebug->coord_tp, emcmotCommand->termCond, emcmotCommand->tolerance);
break;
case EMCMOT_SET_SPINDLESYNC:
tpSetSpindleSync(&emcmotDebug->coord_tp, emcmotCommand->spindle, emcmotCommand->spindlesync, emcmotCommand->flags);
break;
case EMCMOT_SET_LINE:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_LINE");
if (!GET_MOTION_COORD_FLAG() || !GET_MOTION_ENABLE_FLAG()) {
reportError(_("need to be enabled, in coord mode for linear move"));
emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_COMMAND;
SET_MOTION_ERROR_FLAG(1);
break;
} else if (!inRange(emcmotCommand->pos, emcmotCommand->id, "Linear")) {
reportError(_("invalid params in linear command"));
emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
tpAbort(&emcmotDebug->coord_tp);
SET_MOTION_ERROR_FLAG(1);
break;
} else if (!limits_ok()) {
reportError(_("can't do linear move with limits exceeded"));
emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
tpAbort(&emcmotDebug->coord_tp);
SET_MOTION_ERROR_FLAG(1);
break;
}
if(emcmotStatus->atspeed_next_feed && is_feed_type(emcmotCommand->motion_type) ) {
issue_atspeed = 1;
emcmotStatus->atspeed_next_feed = 0;
}
if(!is_feed_type(emcmotCommand->motion_type) &&
emcmotStatus->spindle_status[emcmotCommand->spindle].css_factor) {
emcmotStatus->atspeed_next_feed = 1;
}
tpSetId(&emcmotDebug->coord_tp, emcmotCommand->id);
int res_addline = tpAddLine(&emcmotDebug->coord_tp, emcmotCommand->pos, emcmotCommand->motion_type,
emcmotCommand->vel, emcmotCommand->ini_maxvel,
emcmotCommand->acc, emcmotStatus->enables_new, issue_atspeed,
emcmotCommand->turn);
if (res_addline < 0) {
reportError(_("can't add linear move at line %d, error code %d"),
emcmotCommand->id, res_addline);
emcmotStatus->commandStatus = EMCMOT_COMMAND_BAD_EXEC;
tpAbort(&emcmotDebug->coord_tp);
SET_MOTION_ERROR_FLAG(1);
break;
} else if (res_addline != 0) {
if (issue_atspeed) {
emcmotStatus->atspeed_next_feed = 1;
}
} else {
SET_MOTION_ERROR_FLAG(0);
rehomeAll = 1;
}
break;
case EMCMOT_SET_CIRCLE:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_CIRCLE");
if (!GET_MOTION_COORD_FLAG() || !GET_MOTION_ENABLE_FLAG()) {
reportError(_("need to be enabled, in coord mode for circular move"));
emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_COMMAND;
SET_MOTION_ERROR_FLAG(1);
break;
} else if (!inRange(emcmotCommand->pos, emcmotCommand->id, "Circular")) {
emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
tpAbort(&emcmotDebug->coord_tp);
SET_MOTION_ERROR_FLAG(1);
break;
} else if (!limits_ok()) {
reportError(_("can't do circular move with limits exceeded"));
emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
tpAbort(&emcmotDebug->coord_tp);
SET_MOTION_ERROR_FLAG(1);
break;
}
if(emcmotStatus->atspeed_next_feed) {
issue_atspeed = 1;
emcmotStatus->atspeed_next_feed = 0;
}
tpSetId(&emcmotDebug->coord_tp, emcmotCommand->id);
int res_addcircle = tpAddCircle(&emcmotDebug->coord_tp, emcmotCommand->pos,
emcmotCommand->center, emcmotCommand->normal,
emcmotCommand->turn, emcmotCommand->motion_type,
emcmotCommand->vel, emcmotCommand->ini_maxvel,
emcmotCommand->acc, emcmotStatus->enables_new, issue_atspeed);
if (res_addcircle < 0) {
reportError(_("can't add circular move at line %d, error code %d"),
emcmotCommand->id, res_addcircle);
emcmotStatus->commandStatus = EMCMOT_COMMAND_BAD_EXEC;
tpAbort(&emcmotDebug->coord_tp);
SET_MOTION_ERROR_FLAG(1);
break;
} else if (res_addcircle != 0) {
if (issue_atspeed) {
emcmotStatus->atspeed_next_feed = 1;
}
} else {
SET_MOTION_ERROR_FLAG(0);
rehomeAll = 1;
}
break;
case EMCMOT_SET_VEL:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_VEL");
emcmotStatus->vel = emcmotCommand->vel;
tpSetVmax(&emcmotDebug->coord_tp, emcmotStatus->vel, emcmotCommand->ini_maxvel);
break;
case EMCMOT_SET_VEL_LIMIT:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_VEL_LIMIT");
emcmot_config_change();
emcmotConfig->limitVel = emcmotCommand->vel;
tpSetVlimit(&emcmotDebug->coord_tp, emcmotConfig->limitVel);
break;
case EMCMOT_SET_JOINT_VEL_LIMIT:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_JOINT_VEL_LIMIT");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
emcmot_config_change();
if (joint == 0) {
break;
}
joint->vel_limit = emcmotCommand->vel;
break;
case EMCMOT_SET_JOINT_ACC_LIMIT:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_JOINT_ACC_LIMIT");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
emcmot_config_change();
if (joint == 0) {
break;
}
joint->acc_limit = emcmotCommand->acc;
break;
case EMCMOT_SET_ACC:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_ACCEL");
emcmotStatus->acc = emcmotCommand->acc;
tpSetAmax(&emcmotDebug->coord_tp, emcmotStatus->acc);
break;
case EMCMOT_PAUSE:
rtapi_print_msg(RTAPI_MSG_DBG, "PAUSE");
tpPause(&emcmotDebug->coord_tp);
emcmotStatus->paused = 1;
break;
case EMCMOT_REVERSE:
rtapi_print_msg(RTAPI_MSG_DBG, "REVERSE");
tpSetRunDir(&emcmotDebug->coord_tp, TC_DIR_REVERSE);
break;
case EMCMOT_FORWARD:
rtapi_print_msg(RTAPI_MSG_DBG, "FORWARD");
tpSetRunDir(&emcmotDebug->coord_tp, TC_DIR_FORWARD);
break;
case EMCMOT_RESUME:
rtapi_print_msg(RTAPI_MSG_DBG, "RESUME");
emcmotDebug->stepping = 0;
tpResume(&emcmotDebug->coord_tp);
emcmotStatus->paused = 0;
break;
case EMCMOT_STEP:
rtapi_print_msg(RTAPI_MSG_DBG, "STEP");
if(emcmotStatus->paused) {
emcmotDebug->idForStep = emcmotStatus->id;
emcmotDebug->stepping = 1;
tpResume(&emcmotDebug->coord_tp);
emcmotStatus->paused = 1;
} else {
reportError(_("MOTION: can't STEP while already executing"));
}
break;
case EMCMOT_FEED_SCALE:
rtapi_print_msg(RTAPI_MSG_DBG, "FEED SCALE");
if (emcmotCommand->scale < 0.0) {
emcmotCommand->scale = 0.0;
}
emcmotStatus->feed_scale = emcmotCommand->scale;
break;
case EMCMOT_RAPID_SCALE:
rtapi_print_msg(RTAPI_MSG_DBG, "RAPID SCALE");
if (emcmotCommand->scale < 0.0) {
emcmotCommand->scale = 0.0;
}
emcmotStatus->rapid_scale = emcmotCommand->scale;
break;
case EMCMOT_FS_ENABLE:
if ( emcmotCommand->mode != 0 ) {
rtapi_print_msg(RTAPI_MSG_DBG, "FEED SCALE: ON");
emcmotStatus->enables_new |= FS_ENABLED;
} else {
rtapi_print_msg(RTAPI_MSG_DBG, "FEED SCALE: OFF");
emcmotStatus->enables_new &= ~FS_ENABLED;
}
break;
case EMCMOT_FH_ENABLE:
if ( emcmotCommand->mode != 0 ) {
rtapi_print_msg(RTAPI_MSG_DBG, "FEED HOLD: ENABLED");
emcmotStatus->enables_new |= FH_ENABLED;
} else {
rtapi_print_msg(RTAPI_MSG_DBG, "FEED HOLD: DISABLED");
emcmotStatus->enables_new &= ~FH_ENABLED;
}
break;
case EMCMOT_SPINDLE_SCALE:
rtapi_print_msg(RTAPI_MSG_DBG, "SPINDLE SCALE");
if (emcmotCommand->scale < 0.0) {
emcmotCommand->scale = 0.0;
}
emcmotStatus->spindle_status[emcmotCommand->spindle].scale = emcmotCommand->scale;
break;
case EMCMOT_SS_ENABLE:
if ( emcmotCommand->mode != 0 ) {
rtapi_print_msg(RTAPI_MSG_DBG, "SPINDLE SCALE: ON");
emcmotStatus->enables_new |= SS_ENABLED;
} else {
rtapi_print_msg(RTAPI_MSG_DBG, "SPINDLE SCALE: OFF");
emcmotStatus->enables_new &= ~SS_ENABLED;
}
break;
case EMCMOT_AF_ENABLE:
if ( emcmotCommand->flags != 0 ) {
rtapi_print_msg(RTAPI_MSG_DBG, "ADAPTIVE FEED: ON");
emcmotStatus->enables_new |= AF_ENABLED;
} else {
rtapi_print_msg(RTAPI_MSG_DBG, "ADAPTIVE FEED: OFF");
emcmotStatus->enables_new &= ~AF_ENABLED;
}
break;
case EMCMOT_DISABLE:
rtapi_print_msg(RTAPI_MSG_DBG, "DISABLE");
emcmotDebug->enabling = 0;
if (emcmotConfig->kinType == KINEMATICS_INVERSE_ONLY) {
emcmotDebug->teleoperating = 0;
emcmotDebug->coordinating = 0;
}
break;
case EMCMOT_ENABLE:
rtapi_print_msg(RTAPI_MSG_DBG, "ENABLE");
if ( *(emcmot_hal_data->enable) == 0 ) {
reportError(_("can't enable motion, enable input is false"));
} else {
emcmotDebug->enabling = 1;
if (emcmotConfig->kinType == KINEMATICS_INVERSE_ONLY) {
emcmotDebug->teleoperating = 0;
emcmotDebug->coordinating = 0;
}
}
break;
case EMCMOT_JOINT_ACTIVATE:
rtapi_print_msg(RTAPI_MSG_DBG, "JOINT_ACTIVATE");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
if (joint == 0) {
break;
}
SET_JOINT_ACTIVE_FLAG(joint, 1);
break;
case EMCMOT_JOINT_DEACTIVATE:
rtapi_print_msg(RTAPI_MSG_DBG, "JOINT_DEACTIVATE");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
if (joint == 0) {
break;
}
SET_JOINT_ACTIVE_FLAG(joint, 0);
break;
case EMCMOT_JOINT_ENABLE_AMPLIFIER:
rtapi_print_msg(RTAPI_MSG_DBG, "JOINT_ENABLE_AMP");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
if (joint == 0) {
break;
}
break;
case EMCMOT_JOINT_DISABLE_AMPLIFIER:
rtapi_print_msg(RTAPI_MSG_DBG, "JOINT_DISABLE_AMP");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
if (joint == 0) {
break;
}
break;
case EMCMOT_JOINT_HOME:
rtapi_print_msg(RTAPI_MSG_DBG, "JOINT_HOME");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
if (emcmotStatus->motion_state != EMCMOT_MOTION_FREE) {
reportError(_("must be in joint mode to home"));
return;
}
if (*(emcmot_hal_data->homing_inhibit)) {
reportError(_("Homing denied by motion.homing-inhibit joint=%d\n"),
joint_num);
return;
}
if (!GET_MOTION_ENABLE_FLAG()) {
break;
}
if(joint_num == -1) { if(get_home_sequence_state() == HOME_SEQUENCE_IDLE) {
set_home_sequence_state(HOME_SEQUENCE_START);
} else {
reportError(_("homing sequence already in progress"));
}
break; }
if (joint == NULL) { break; }
joint->free_tp.enable = 0;
if (get_home_sequence(joint_num) < 0) {
int jj;
set_home_sequence_state(HOME_SEQUENCE_DO_ONE_SEQUENCE);
for (jj = 0; jj < ALL_JOINTS; jj++) {
if (ABS(get_home_sequence(jj)) == ABS(get_home_sequence(joint_num))) {
set_home_start(jj);
}
}
break;
} else {
set_home_sequence_state(HOME_SEQUENCE_DO_ONE_JOINT);
set_home_start(joint_num); }
break;
case EMCMOT_JOINT_UNHOME:
rtapi_print_msg(RTAPI_MSG_DBG, "JOINT_UNHOME");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", joint_num);
if ( (emcmotStatus->motion_state != EMCMOT_MOTION_FREE)
&& (emcmotStatus->motion_state != EMCMOT_MOTION_DISABLED)) {
reportError(_("must be in joint mode or disabled to unhome"));
return;
}
if (joint_num < 0) {
for (n = 0; n < ALL_JOINTS; n++) {
joint = &joints[n];
if(GET_JOINT_ACTIVE_FLAG(joint)) {
if (get_homing(n)) {
reportError(_("Cannot unhome while homing, joint %d"), n);
return;
}
if (!GET_JOINT_INPOS_FLAG(joint)) {
reportError(_("Cannot unhome while moving, joint %d"), n);
return;
}
}
if ( (n >= NO_OF_KINS_JOINTS)
&& (emcmotStatus->motion_state != EMCMOT_MOTION_DISABLED)) {
reportError(_("Cannot unhome extrajoint <%d> with motion enabled"), n);
return;
}
}
for (n = 0; n < ALL_JOINTS; n++) {
joint = &joints[n];
if(GET_JOINT_ACTIVE_FLAG(joint)) {
if( (joint_num != -2) || get_home_is_volatile(n) ) {
set_joint_homed(n, 0);
}
}
}
} else if (joint_num < ALL_JOINTS) {
if ( (joint_num >= NO_OF_KINS_JOINTS)
&& (emcmotStatus->motion_state != EMCMOT_MOTION_DISABLED)) {
reportError(_("Cannot unhome extrajoint <%d> with motion enabled"), joint_num);
return;
}
if(GET_JOINT_ACTIVE_FLAG(joint)) {
if (get_homing(joint_num) ) {
reportError(_("Cannot unhome while homing, joint %d"), joint_num);
return;
}
if (!GET_JOINT_INPOS_FLAG(joint)) {
reportError(_("Cannot unhome while moving, joint %d"), joint_num);
return;
}
set_joint_homed(joint_num, 0);
} else {
reportError(_("Cannot unhome inactive joint %d"), joint_num);
}
} else {
reportError(_("Cannot unhome invalid joint %d (max %d)"), joint_num, (ALL_JOINTS-1));
return;
}
break;
case EMCMOT_CLEAR_PROBE_FLAGS:
rtapi_print_msg(RTAPI_MSG_DBG, "CLEAR_PROBE_FLAGS");
emcmotStatus->probing = 0;
emcmotStatus->probeTripped = 0;
break;
case EMCMOT_PROBE:
rtapi_print_msg(RTAPI_MSG_DBG, "PROBE");
if (!GET_MOTION_COORD_FLAG() || !GET_MOTION_ENABLE_FLAG()) {
reportError(_("need to be enabled, in coord mode for probe move"));
emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_COMMAND;
SET_MOTION_ERROR_FLAG(1);
break;
} else if (!inRange(emcmotCommand->pos, emcmotCommand->id, "Probe")) {
emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
tpAbort(&emcmotDebug->coord_tp);
SET_MOTION_ERROR_FLAG(1);
break;
} else if (!limits_ok()) {
reportError(_("can't do probe move with limits exceeded"));
emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
tpAbort(&emcmotDebug->coord_tp);
SET_MOTION_ERROR_FLAG(1);
break;
} else if (!(emcmotCommand->probe_type & 1)) {
int probeval = !!*(emcmot_hal_data->probe_input);
int probe_whenclears = !!(emcmotCommand->probe_type & 2);
if (probeval != probe_whenclears) {
if(probe_whenclears)
reportError(_("Probe is already clear when starting G38.4 or G38.5 move"));
else
reportError(_("Probe is already tripped when starting G38.2 or G38.3 move"));
emcmotStatus->commandStatus = EMCMOT_COMMAND_BAD_EXEC;
tpAbort(&emcmotDebug->coord_tp);
SET_MOTION_ERROR_FLAG(1);
break;
}
}
tpSetId(&emcmotDebug->coord_tp, emcmotCommand->id);
if (-1 == tpAddLine(&emcmotDebug->coord_tp, emcmotCommand->pos, emcmotCommand->motion_type, emcmotCommand->vel, emcmotCommand->ini_maxvel, emcmotCommand->acc, emcmotStatus->enables_new, 0, -1)) {
reportError(_("can't add probe move"));
emcmotStatus->commandStatus = EMCMOT_COMMAND_BAD_EXEC;
tpAbort(&emcmotDebug->coord_tp);
SET_MOTION_ERROR_FLAG(1);
break;
} else {
emcmotStatus->probing = 1;
emcmotStatus->probe_type = emcmotCommand->probe_type;
SET_MOTION_ERROR_FLAG(0);
rehomeAll = 1;
}
break;
case EMCMOT_RIGID_TAP:
rtapi_print_msg(RTAPI_MSG_DBG, "RIGID_TAP");
if (!GET_MOTION_COORD_FLAG() || !GET_MOTION_ENABLE_FLAG()) {
reportError(_("need to be enabled, in coord mode for rigid tap move"));
emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_COMMAND;
SET_MOTION_ERROR_FLAG(1);
break;
} else if (!inRange(emcmotCommand->pos, emcmotCommand->id, "Rigid tap")) {
emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
tpAbort(&emcmotDebug->coord_tp);
SET_MOTION_ERROR_FLAG(1);
break;
} else if (!limits_ok()) {
reportError(_("can't do rigid tap move with limits exceeded"));
emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
tpAbort(&emcmotDebug->coord_tp);
SET_MOTION_ERROR_FLAG(1);
break;
}
tpSetId(&emcmotDebug->coord_tp, emcmotCommand->id);
int res_addtap = tpAddRigidTap(&emcmotDebug->coord_tp, emcmotCommand->pos, emcmotCommand->vel, emcmotCommand->ini_maxvel, emcmotCommand->acc, emcmotStatus->enables_new, emcmotCommand->scale);
if (res_addtap < 0) {
emcmotStatus->atspeed_next_feed = 0;
reportError(_("can't add rigid tap move at line %d, error code %d"),
emcmotCommand->id, res_addtap);
tpAbort(&emcmotDebug->coord_tp);
SET_MOTION_ERROR_FLAG(1);
break;
} else {
SET_MOTION_ERROR_FLAG(0);
}
break;
case EMCMOT_SET_DEBUG:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_DEBUG");
emcmotConfig->debug = emcmotCommand->debug;
emcmot_config_change();
break;
case EMCMOT_SET_AOUT:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_AOUT");
if (emcmotCommand->now) { emcmotAioWrite(emcmotCommand->out, emcmotCommand->minLimit);
} else { tpSetAout(&emcmotDebug->coord_tp, emcmotCommand->out,
emcmotCommand->minLimit, emcmotCommand->maxLimit);
}
break;
case EMCMOT_SET_DOUT:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_DOUT");
if (emcmotCommand->now) { emcmotDioWrite(emcmotCommand->out, emcmotCommand->start);
} else { tpSetDout(&emcmotDebug->coord_tp, emcmotCommand->out,
emcmotCommand->start, emcmotCommand->end);
}
break;
case EMCMOT_SPINDLE_ON:
rtapi_print_msg(RTAPI_MSG_DBG, "SPINDLE_ON: spindle %d/%d speed %d\n",
emcmotCommand->spindle, emcmotConfig->numSpindles, (int) emcmotCommand->vel);
spindle_num = emcmotCommand->spindle;
if (spindle_num >= emcmotConfig->numSpindles){
reportError(_("Attempt to start non-existent spindle"));
emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_COMMAND;
break;
}
if (*(emcmot_hal_data->spindle[spindle_num].spindle_orient))
rtapi_print_msg(RTAPI_MSG_DBG, "SPINDLE_ORIENT cancelled by SPINDLE_ON\n");
if (*(emcmot_hal_data->spindle[spindle_num].spindle_locked))
rtapi_print_msg(RTAPI_MSG_DBG, "spindle-locked cleared by SPINDLE_ON\n");
*(emcmot_hal_data->spindle[spindle_num].spindle_locked) = 0;
*(emcmot_hal_data->spindle[spindle_num].spindle_orient) = 0;
emcmotStatus->spindle_status[spindle_num].orient_state = EMCMOT_ORIENT_NONE;
emcmotStatus->spindle_status[spindle_num].speed = emcmotCommand->vel;
emcmotStatus->spindle_status[spindle_num].css_factor = emcmotCommand->ini_maxvel;
emcmotStatus->spindle_status[spindle_num].xoffset = emcmotCommand->acc;
if (emcmotCommand->vel >= 0) {
emcmotStatus->spindle_status[spindle_num].direction = 1;
} else {
emcmotStatus->spindle_status[spindle_num].direction = -1;
}
emcmotStatus->spindle_status[spindle_num].brake = 0; emcmotStatus->atspeed_next_feed = emcmotCommand->wait_for_spindle_at_speed;
if (!emcmotStatus->atspeed_next_feed)
rtapi_print_msg(RTAPI_MSG_DBG, "SPINDLE_ON without wait-for-atspeed");
break;
case EMCMOT_SPINDLE_OFF:
rtapi_print_msg(RTAPI_MSG_DBG, "SPINDLE_OFF");
spindle_num = emcmotCommand->spindle;
if (spindle_num >= emcmotConfig->numSpindles){
reportError(_("Attempt to stop non-existent spindle <%d>"),spindle_num);
emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_COMMAND;
break;
}
emcmotStatus->spindle_status[spindle_num].speed = 0;
emcmotStatus->spindle_status[spindle_num].direction = 0;
emcmotStatus->spindle_status[spindle_num].brake = 1; if (*(emcmot_hal_data->spindle[spindle_num].spindle_orient))
rtapi_print_msg(RTAPI_MSG_DBG, "SPINDLE_ORIENT cancelled by SPINDLE_OFF");
if (*(emcmot_hal_data->spindle[spindle_num].spindle_locked))
rtapi_print_msg(RTAPI_MSG_DBG, "spindle-locked cleared by SPINDLE_OFF");
*(emcmot_hal_data->spindle[spindle_num].spindle_locked) = 0;
*(emcmot_hal_data->spindle[spindle_num].spindle_orient) = 0;
emcmotStatus->spindle_status[spindle_num].orient_state = EMCMOT_ORIENT_NONE;
break;
case EMCMOT_SPINDLE_ORIENT:
rtapi_print_msg(RTAPI_MSG_DBG, "SPINDLE_ORIENT");
spindle_num = emcmotCommand->spindle;
if (spindle_num >= emcmotConfig->numSpindles){
reportError(_("Attempt to orient non-existent spindle <%d>"),spindle_num);
emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_COMMAND;
break;
}
if (spindle_num > emcmotConfig->numSpindles){
rtapi_print_msg(RTAPI_MSG_ERR, "spindle number <%d> too high in M19",spindle_num);
break;
}
if (*(emcmot_hal_data->spindle[spindle_num].spindle_orient)) {
rtapi_print_msg(RTAPI_MSG_DBG, "orient already in progress");
}
emcmotStatus->spindle_status[spindle_num].orient_state = EMCMOT_ORIENT_IN_PROGRESS;
emcmotStatus->spindle_status[spindle_num].speed = 0;
emcmotStatus->spindle_status[spindle_num].direction = 0;
emcmotStatus->spindle_status[spindle_num].brake = 0;
*(emcmot_hal_data->spindle[spindle_num].spindle_orient_angle) = emcmotCommand->orientation;
*(emcmot_hal_data->spindle[spindle_num].spindle_orient_mode) = emcmotCommand->mode;
*(emcmot_hal_data->spindle[spindle_num].spindle_locked) = 0;
*(emcmot_hal_data->spindle[spindle_num].spindle_orient) = 1;
emcmotStatus->spindle_status[spindle_num].orient_fault = 0; emcmotStatus->spindle_status[spindle_num].locked = 0;
break;
case EMCMOT_SPINDLE_INCREASE:
rtapi_print_msg(RTAPI_MSG_DBG, "SPINDLE_INCREASE");
spindle_num = emcmotCommand->spindle;
if (spindle_num >= emcmotConfig->numSpindles){
reportError(_("Attempt to increase non-existent spindle <%d>"),spindle_num);
emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_COMMAND;
break;
}
if (emcmotStatus->spindle_status[spindle_num].speed > 0) {
emcmotStatus->spindle_status[spindle_num].speed += 100; } else if (emcmotStatus->spindle_status[spindle_num].speed < 0) {
emcmotStatus->spindle_status[spindle_num].speed -= 100;
}
break;
case EMCMOT_SPINDLE_DECREASE:
rtapi_print_msg(RTAPI_MSG_DBG, "SPINDLE_DECREASE");
spindle_num = emcmotCommand->spindle;
if (spindle_num >= emcmotConfig->numSpindles){
reportError(_("Attempt to decreasenon-existent spindle <%d>"),spindle_num);
emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_COMMAND;
break;
}
if (emcmotStatus->spindle_status[spindle_num].speed > 100) {
emcmotStatus->spindle_status[spindle_num].speed -= 100; } else if (emcmotStatus->spindle_status[spindle_num].speed < -100) {
emcmotStatus->spindle_status[spindle_num].speed += 100;
}
break;
case EMCMOT_SPINDLE_BRAKE_ENGAGE:
rtapi_print_msg(RTAPI_MSG_DBG, "SPINDLE_BRAKE_ENGAGE");
spindle_num = emcmotCommand->spindle;
if (spindle_num >= emcmotConfig->numSpindles){
reportError(_("Attempt to engage brake of non-existent spindle <%d>"),spindle_num);
emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_COMMAND;
break;
}
emcmotStatus->spindle_status[spindle_num].speed = 0;
emcmotStatus->spindle_status[spindle_num].direction = 0;
emcmotStatus->spindle_status[spindle_num].brake = 1;
break;
case EMCMOT_SPINDLE_BRAKE_RELEASE:
rtapi_print_msg(RTAPI_MSG_DBG, "SPINDLE_BRAKE_RELEASE");
spindle_num = emcmotCommand->spindle;
if (spindle_num >= emcmotConfig->numSpindles){
reportError(_("Attempt to release brake of non-existent spindle <%d>"),spindle_num);
emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_COMMAND;
break;
}
emcmotStatus->spindle_status[spindle_num].brake = 0;
break;
case EMCMOT_SET_JOINT_COMP:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_JOINT_COMP for joint %d", joint_num);
if (joint == 0) {
break;
}
if (joint->comp.entries >= EMCMOT_COMP_SIZE) {
reportError(_("joint %d: too many compensation entries"), joint_num);
break;
}
comp_entry = &(joint->comp.array[joint->comp.entries]);
if (emcmotCommand->comp_nominal <= comp_entry[0].nominal) {
reportError(_("joint %d: compensation values must increase"), joint_num);
break;
}
comp_entry[1].nominal = emcmotCommand->comp_nominal;
comp_entry[1].fwd_trim = emcmotCommand->comp_forward;
comp_entry[1].rev_trim = emcmotCommand->comp_reverse;
if ( comp_entry[0].nominal != -DBL_MAX ) {
tmp1 = comp_entry[1].nominal - comp_entry[0].nominal;
comp_entry[0].fwd_slope =
(comp_entry[1].fwd_trim - comp_entry[0].fwd_trim) / tmp1;
comp_entry[0].rev_slope =
(comp_entry[1].rev_trim - comp_entry[0].rev_trim) / tmp1;
} else {
comp_entry[0].fwd_trim = comp_entry[1].fwd_trim;
comp_entry[0].rev_trim = comp_entry[1].rev_trim;
}
joint->comp.entries++;
break;
case EMCMOT_SET_OFFSET:
emcmotStatus->tool_offset = emcmotCommand->tool_offset;
break;
case EMCMOT_SET_AXIS_POSITION_LIMITS:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_AXIS_POSITION_LIMITS");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", axis_num);
emcmot_config_change();
if (axis == 0) {
break;
}
axis->min_pos_limit = emcmotCommand->minLimit;
axis->max_pos_limit = emcmotCommand->maxLimit;
break;
case EMCMOT_SET_AXIS_VEL_LIMIT:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_AXIS_VEL_LIMITS");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", axis_num);
emcmot_config_change();
if (axis == 0) {
break;
}
axis->vel_limit = emcmotCommand->vel;
axis->ext_offset_vel_limit = emcmotCommand->ext_offset_vel;
break;
case EMCMOT_SET_AXIS_ACC_LIMIT:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_AXIS_ACC_LIMITS");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", axis_num);
emcmot_config_change();
if (axis == 0) {
break;
}
axis->acc_limit = emcmotCommand->acc;
axis->ext_offset_acc_limit = emcmotCommand->ext_offset_acc;
break;
case EMCMOT_SET_AXIS_LOCKING_JOINT:
rtapi_print_msg(RTAPI_MSG_DBG, "SET_AXIS_ACC_LOCKING_JOINT");
rtapi_print_msg(RTAPI_MSG_DBG, " %d", axis_num);
emcmot_config_change();
if (axis == 0) {
break;
}
axis->locking_joint = joint_num;
break;
default:
rtapi_print_msg(RTAPI_MSG_DBG, "UNKNOWN");
reportError(_("unrecognized command %d"), emcmotCommand->command);
emcmotStatus->commandStatus = EMCMOT_COMMAND_UNKNOWN_COMMAND;
break;
case EMCMOT_SET_MAX_FEED_OVERRIDE:
emcmotConfig->maxFeedScale = emcmotCommand->maxFeedScale;
break;
case EMCMOT_SETUP_ARC_BLENDS:
emcmotConfig->arcBlendEnable = emcmotCommand->arcBlendEnable;
emcmotConfig->arcBlendFallbackEnable = emcmotCommand->arcBlendFallbackEnable;
emcmotConfig->arcBlendOptDepth = emcmotCommand->arcBlendOptDepth;
emcmotConfig->arcBlendGapCycles = emcmotCommand->arcBlendGapCycles;
emcmotConfig->arcBlendRampFreq = emcmotCommand->arcBlendRampFreq;
emcmotConfig->arcBlendTangentKinkRatio = emcmotCommand->arcBlendTangentKinkRatio;
break;
case EMCMOT_SET_PROBE_ERR_INHIBIT:
emcmotConfig->inhibit_probe_jog_error = emcmotCommand->probe_jog_err_inhibit;
emcmotConfig->inhibit_probe_home_error = emcmotCommand->probe_home_err_inhibit;
break;
}
if (emcmotStatus->commandStatus != EMCMOT_COMMAND_OK) {
rtapi_print_msg(RTAPI_MSG_DBG, "ERROR: %d",
emcmotStatus->commandStatus);
}
rtapi_print_msg(RTAPI_MSG_DBG, "\n");
emcmotStatus->tail = emcmotStatus->head;
emcmotConfig->tail = emcmotConfig->head;
emcmotDebug->tail = emcmotDebug->head;
}
return;
}