#include <cmath>
#include <float.h>
#include <string.h>
#include <unistd.h>
#include "usrmotintf.h"
#include "motion.h"
#include "motion_debug.h"
#include "emc.hh"
#include "emccfg.h"
#include "emcglb.h"
#include "emc_nml.hh"
#include "rcs_print.hh"
#include "timer.hh"
#include "inifile.hh"
#include "iniaxis.hh"
#include "inijoint.hh"
#include "initraj.hh"
#include "inihal.hh"
value_inihal_data old_inihal_data;
#define ISNAN_TRAP
#ifdef ISNAN_TRAP
#define CATCH_NAN(cond) do { \
if (cond) { \
printf("isnan error in %s()\n", __FUNCTION__); \
return -1; \
} \
} while(0)
#else
#define CATCH_NAN(cond) do {} while(0)
#endif
static emcmot_status_t emcmotStatus;
static struct TrajConfig_t TrajConfig;
static struct JointConfig_t JointConfig[EMCMOT_MAX_JOINTS];
static struct AxisConfig_t AxisConfig[EMCMOT_MAX_AXIS];
static emcmot_command_t emcmotCommand;
__attribute__ ((unused))
static int emcmotIoInited = 0; static int emcmotion_initialized = 0;
static unsigned long localMotionHeartbeat = 0;
static int localMotionCommandType = 0;
static int localMotionEchoSerialNumber = 0;
int emcJointSetType(int joint, unsigned char jointType)
{
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
JointConfig[joint].Type = jointType;
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d, %d)\n", __FUNCTION__, joint, jointType);
}
return 0;
}
int emcJointSetUnits(int joint, double units)
{
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
JointConfig[joint].Units = units;
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d, %.4f)\n", __FUNCTION__, joint, units);
}
return 0;
}
int emcJointSetBacklash(int joint, double backlash)
{
#ifdef ISNAN_TRAP
if (std::isnan(backlash)) {
printf("std::isnan error in emcJointSetBacklash()\n");
return -1;
}
#endif
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
emcmotCommand.command = EMCMOT_SET_JOINT_BACKLASH;
emcmotCommand.joint = joint;
emcmotCommand.backlash = backlash;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d, %.4f) returned %d\n", __FUNCTION__, joint, backlash, retval);
}
return retval;
}
int emcJointSetMinPositionLimit(int joint, double limit)
{
#ifdef ISNAN_TRAP
if (std::isnan(limit)) {
printf("isnan error in emcJointSetMinPosition()\n");
return -1;
}
#endif
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
JointConfig[joint].MinLimit = limit;
emcmotCommand.command = EMCMOT_SET_JOINT_POSITION_LIMITS;
emcmotCommand.joint = joint;
emcmotCommand.minLimit = JointConfig[joint].MinLimit;
emcmotCommand.maxLimit = JointConfig[joint].MaxLimit;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d, %.4f) returned %d\n", __FUNCTION__, joint, limit, retval);
}
return retval;
}
int emcJointSetMaxPositionLimit(int joint, double limit)
{
#ifdef ISNAN_TRAP
if (std::isnan(limit)) {
printf("std::isnan error in emcJointSetMaxPosition()\n");
return -1;
}
#endif
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
JointConfig[joint].MaxLimit = limit;
emcmotCommand.command = EMCMOT_SET_JOINT_POSITION_LIMITS;
emcmotCommand.joint = joint;
emcmotCommand.minLimit = JointConfig[joint].MinLimit;
emcmotCommand.maxLimit = JointConfig[joint].MaxLimit;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d, %.4f) returned %d\n", __FUNCTION__, joint, limit, retval);
}
return retval;
}
int emcJointSetMotorOffset(int joint, double offset)
{
#ifdef ISNAN_TRAP
if (std::isnan(offset)) {
printf("isnan error in emcJointSetMotorOffset()\n");
return -1;
}
#endif
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
emcmotCommand.command = EMCMOT_SET_JOINT_MOTOR_OFFSET;
emcmotCommand.joint = joint;
emcmotCommand.motor_offset = offset;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d, %.4f) returned %d\n", __FUNCTION__, joint, offset, retval);
}
return retval;
}
int emcJointSetFerror(int joint, double ferror)
{
#ifdef ISNAN_TRAP
if (std::isnan(ferror)) {
printf("isnan error in emcJointSetFerror()\n");
return -1;
}
#endif
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
emcmotCommand.command = EMCMOT_SET_JOINT_MAX_FERROR;
emcmotCommand.joint = joint;
emcmotCommand.maxFerror = ferror;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d, %.4f) returned %d\n", __FUNCTION__, joint, ferror, retval);
}
return retval;
}
int emcJointSetMinFerror(int joint, double ferror)
{
#ifdef ISNAN_TRAP
if (std::isnan(ferror)) {
printf("isnan error in emcJointSetMinFerror()\n");
return -1;
}
#endif
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
emcmotCommand.command = EMCMOT_SET_JOINT_MIN_FERROR;
emcmotCommand.joint = joint;
emcmotCommand.minFerror = ferror;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d, %.4f) returned %d\n", __FUNCTION__, joint, ferror, retval);
}
return retval;
}
int emcJointSetHomingParams(int joint, double home, double offset, double home_final_vel,
double search_vel, double latch_vel,
int use_index, int encoder_does_not_reset,
int ignore_limits, int is_shared,
int sequence,int volatile_home, int locking_indexer,int absolute_encoder)
{
#ifdef ISNAN_TRAP
if (std::isnan(home) || std::isnan(offset) || std::isnan(home_final_vel) ||
std::isnan(search_vel) || std::isnan(latch_vel)) {
printf("isnan error in emcJointSetHomingParams()\n");
return -1;
}
#endif
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
emcmotCommand.command = EMCMOT_SET_JOINT_HOMING_PARAMS;
emcmotCommand.joint = joint;
emcmotCommand.home = home;
emcmotCommand.offset = offset;
emcmotCommand.home_final_vel = home_final_vel;
emcmotCommand.search_vel = search_vel;
emcmotCommand.latch_vel = latch_vel;
emcmotCommand.flags = 0;
emcmotCommand.home_sequence = sequence;
emcmotCommand.volatile_home = volatile_home;
if (use_index) {
emcmotCommand.flags |= HOME_USE_INDEX;
}
if (encoder_does_not_reset) {
emcmotCommand.flags |= HOME_INDEX_NO_ENCODER_RESET;
}
if (ignore_limits) {
emcmotCommand.flags |= HOME_IGNORE_LIMITS;
}
if (is_shared) {
emcmotCommand.flags |= HOME_IS_SHARED;
}
if (locking_indexer) {
emcmotCommand.flags |= HOME_UNLOCK_FIRST;
}
if (absolute_encoder) {
switch (absolute_encoder) {
case 0: break;
case 1: emcmotCommand.flags |= HOME_ABSOLUTE_ENCODER;
emcmotCommand.flags |= HOME_NO_REHOME;
break;
case 2: emcmotCommand.flags |= HOME_ABSOLUTE_ENCODER;
emcmotCommand.flags |= HOME_NO_REHOME;
emcmotCommand.flags |= HOME_NO_FINAL_MOVE;
break;
default: fprintf(stderr,
"Unknown option for absolute_encoder <%d>",absolute_encoder);
break;
}
}
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d, %.4f, %.4f, %.4f, %.4f, %.4f, %d, %d, %d, %d, %d) returned %d\n",
__FUNCTION__, joint, home, offset, home_final_vel, search_vel, latch_vel,
use_index, ignore_limits, is_shared, sequence, volatile_home, retval);
}
return retval;
}
int emcJointUpdateHomingParams(int joint, double home, double offset, int sequence)
{
CATCH_NAN(std::isnan(home) || std::isnan(offset) );
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
emcmotCommand.command = EMCMOT_UPDATE_JOINT_HOMING_PARAMS;
emcmotCommand.joint = joint;
emcmotCommand.home = home;
emcmotCommand.offset = offset;
emcmotCommand.home_sequence = sequence;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d, %.4f, %.4f) returned %d\n",
__FUNCTION__, joint, home, offset,retval);
}
return retval;
}
int emcJointSetMaxVelocity(int joint, double vel)
{
CATCH_NAN(std::isnan(vel));
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
if (vel < 0.0) {
vel = 0.0;
}
JointConfig[joint].MaxVel = vel;
emcmotCommand.command = EMCMOT_SET_JOINT_VEL_LIMIT;
emcmotCommand.joint = joint;
emcmotCommand.vel = vel;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d, %.4f) returned %d\n", __FUNCTION__, joint, vel, retval);
}
return retval;
}
int emcJointSetMaxAcceleration(int joint, double acc)
{
CATCH_NAN(std::isnan(acc));
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
if (acc < 0.0) {
acc = 0.0;
}
JointConfig[joint].MaxAccel = acc;
emcmotCommand.command = EMCMOT_SET_JOINT_ACC_LIMIT;
emcmotCommand.joint = joint;
emcmotCommand.acc = acc;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d, %.4f) returned %d\n", __FUNCTION__, joint, acc, retval);
}
return retval;
}
int emcAxisSetMinPositionLimit(int axis, double limit)
{
CATCH_NAN(std::isnan(limit));
if (axis < 0 || axis >= EMCMOT_MAX_AXIS || !(TrajConfig.AxisMask & (1 << axis))) {
return 0;
}
AxisConfig[axis].MinLimit = limit;
emcmotCommand.command = EMCMOT_SET_AXIS_POSITION_LIMITS;
emcmotCommand.axis = axis;
emcmotCommand.minLimit = AxisConfig[axis].MinLimit;
emcmotCommand.maxLimit = AxisConfig[axis].MaxLimit;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d, %.4f) returned %d\n", __FUNCTION__, axis, limit, retval);
}
return retval;
}
int emcAxisSetMaxPositionLimit(int axis, double limit)
{
CATCH_NAN(std::isnan(limit));
if (axis < 0 || axis >= EMCMOT_MAX_AXIS || !(TrajConfig.AxisMask & (1 << axis))) {
return 0;
}
AxisConfig[axis].MaxLimit = limit;
emcmotCommand.command = EMCMOT_SET_AXIS_POSITION_LIMITS;
emcmotCommand.axis = axis;
emcmotCommand.minLimit = AxisConfig[axis].MinLimit;
emcmotCommand.maxLimit = AxisConfig[axis].MaxLimit;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d, %.4f) returned %d\n", __FUNCTION__, axis, limit, retval);
}
return retval;
}
int emcAxisSetMaxVelocity(int axis, double vel,double ext_offset_vel)
{
CATCH_NAN(std::isnan(vel));
if (axis < 0 || axis >= EMCMOT_MAX_AXIS || !(TrajConfig.AxisMask & (1 << axis))) {
return 0;
}
if (vel < 0.0) {
vel = 0.0;
}
AxisConfig[axis].MaxVel = vel;
emcmotCommand.command = EMCMOT_SET_AXIS_VEL_LIMIT;
emcmotCommand.axis = axis;
emcmotCommand.vel = vel;
emcmotCommand.ext_offset_vel = ext_offset_vel;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d, %.4f) returned %d\n", __FUNCTION__, axis, vel, retval);
}
return retval;
}
int emcAxisSetMaxAcceleration(int axis, double acc,double ext_offset_acc)
{
CATCH_NAN(std::isnan(acc));
if (axis < 0 || axis >= EMCMOT_MAX_AXIS || !(TrajConfig.AxisMask & (1 << axis))) {
return 0;
}
if (acc < 0.0) {
acc = 0.0;
}
AxisConfig[axis].MaxAccel = acc;
emcmotCommand.command = EMCMOT_SET_AXIS_ACC_LIMIT;
emcmotCommand.axis = axis;
emcmotCommand.acc = acc;
emcmotCommand.ext_offset_acc = ext_offset_acc;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d, %.4f) returned %d\n", __FUNCTION__, axis, acc, retval);
}
return retval;
}
int emcAxisSetLockingJoint(int axis, int joint)
{
if (axis < 0 || axis >= EMCMOT_MAX_AXIS || !(TrajConfig.AxisMask & (1 << axis))) {
return 0;
}
if (joint < 0) {
joint = -1;
}
emcmotCommand.command = EMCMOT_SET_AXIS_LOCKING_JOINT;
emcmotCommand.axis = axis;
emcmotCommand.joint = joint;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d, %d) returned %d\n", __FUNCTION__, axis, joint, retval);
}
return retval;
}
double emcAxisGetMaxVelocity(int axis)
{
if (axis < 0 || axis >= EMCMOT_MAX_AXIS) {
return 0;
}
return AxisConfig[axis].MaxVel;
}
double emcAxisGetMaxAcceleration(int axis)
{
if (axis < 0 || axis >= EMCMOT_MAX_AXIS) {
return 0;
}
return AxisConfig[axis].MaxAccel;
}
int emcAxisUpdate(EMC_AXIS_STAT stat[], int axis_mask)
{
int axis_num;
emcmot_axis_status_t *axis;
for (axis_num = 0; axis_num < EMCMOT_MAX_AXIS; axis_num++) {
if(!(axis_mask & (1 << axis_num))) continue;
axis = &(emcmotStatus.axis_status[axis_num]);
stat[axis_num].velocity = axis->teleop_vel_cmd;
stat[axis_num].minPositionLimit = axis->min_pos_limit;
stat[axis_num].maxPositionLimit = axis->max_pos_limit;
}
return 0;
}
static int JointOrTrajInited(void)
{
int joint;
for (joint = 0; joint < EMCMOT_MAX_JOINTS; joint++) {
if (JointConfig[joint].Inited) {
return 1;
}
}
if (TrajConfig.Inited) {
return 1;
}
return 0;
}
int emcJointInit(int joint)
{
int retval = 0;
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
if (!JointOrTrajInited()) {
usrmotIniLoad(emc_inifile);
if (0 != usrmotInit("emc2_task")) {
return -1;
}
}
JointConfig[joint].Inited = 1;
if (0 != iniJoint(joint, emc_inifile)) {
retval = -1;
}
return retval;
}
int emcAxisInit(int axis)
{
int retval = 0;
if (axis < 0 || axis >= EMCMOT_MAX_AXIS) {
return 0;
}
if (!JointOrTrajInited()) {
usrmotIniLoad(emc_inifile);
if (0 != usrmotInit("emc2_task")) {
return -1;
}
}
AxisConfig[axis].Inited = 1;
if (0 != iniAxis(axis, emc_inifile)) {
retval = -1;
}
return retval;
}
int emcJointHalt(int joint)
{
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
if (NULL != emcStatus && emcmotion_initialized
&& JointConfig[joint].Inited) {
}
JointConfig[joint].Inited = 0;
if (!JointOrTrajInited()) {
usrmotExit(); }
return 0;
}
int emcJointAbort(int joint)
{
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
emcmotCommand.command = EMCMOT_JOINT_ABORT;
emcmotCommand.joint = joint;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcJointActivate(int joint)
{
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
emcmotCommand.command = EMCMOT_JOINT_ACTIVATE;
emcmotCommand.joint = joint;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d) returned %d\n", __FUNCTION__, joint, retval);
}
return retval;
}
int emcJointDeactivate(int joint)
{
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
emcmotCommand.command = EMCMOT_JOINT_DEACTIVATE;
emcmotCommand.joint = joint;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcJointOverrideLimits(int joint)
{
if (joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
emcmotCommand.command = EMCMOT_OVERRIDE_LIMITS;
emcmotCommand.joint = joint;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcJointEnable(int joint)
{
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
emcmotCommand.command = EMCMOT_JOINT_ENABLE_AMPLIFIER;
emcmotCommand.joint = joint;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcJointDisable(int joint)
{
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
emcmotCommand.command = EMCMOT_JOINT_DISABLE_AMPLIFIER;
emcmotCommand.joint = joint;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcJointHome(int joint)
{
if (joint < -1 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
emcmotCommand.command = EMCMOT_JOINT_HOME;
emcmotCommand.joint = joint;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcJointUnhome(int joint)
{
if (joint < -2 || joint >= EMCMOT_MAX_JOINTS) {
return 0;
}
emcmotCommand.command = EMCMOT_JOINT_UNHOME;
emcmotCommand.joint = joint;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcJogCont(int nr, double vel, int jjogmode)
{
if (jjogmode) {
if (nr < 0 || nr >= EMCMOT_MAX_JOINTS) { return 0; }
if (vel > JointConfig[nr].MaxVel) {
vel = JointConfig[nr].MaxVel;
} else if (vel < -JointConfig[nr].MaxVel) {
vel = -JointConfig[nr].MaxVel;
}
emcmotCommand.joint = nr;
emcmotCommand.axis = -1; } else {
if (nr < 0 || nr >= EMCMOT_MAX_AXIS) { return 0; }
if (vel > AxisConfig[nr].MaxVel) {
vel = AxisConfig[nr].MaxVel;
} else if (vel < -AxisConfig[nr].MaxVel) {
vel = -AxisConfig[nr].MaxVel;
}
emcmotCommand.joint = -1; emcmotCommand.axis = nr;
}
emcmotCommand.command = EMCMOT_JOG_CONT;
emcmotCommand.vel = vel;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcJogIncr(int nr, double incr, double vel, int jjogmode)
{
if (jjogmode) {
if (nr < 0 || nr >= EMCMOT_MAX_JOINTS) { return 0; }
if (vel > JointConfig[nr].MaxVel) {
vel = JointConfig[nr].MaxVel;
} else if (vel < -JointConfig[nr].MaxVel) {
vel = -JointConfig[nr].MaxVel;
}
emcmotCommand.joint = nr;
emcmotCommand.axis = -1; } else {
if (nr < 0 || nr >= EMCMOT_MAX_AXIS) { return 0; }
if (vel > AxisConfig[nr].MaxVel) {
vel = AxisConfig[nr].MaxVel;
} else if (vel < -AxisConfig[nr].MaxVel) {
vel = -AxisConfig[nr].MaxVel;
}
emcmotCommand.joint = -1; emcmotCommand.axis = nr;
}
emcmotCommand.command = EMCMOT_JOG_INCR;
emcmotCommand.vel = vel;
emcmotCommand.offset = incr;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcJogAbs(int nr, double pos, double vel, int jjogmode)
{
if (jjogmode) {
if (nr < 0 || nr >= EMCMOT_MAX_JOINTS) { return 0; }
if (vel > JointConfig[nr].MaxVel) {
vel = JointConfig[nr].MaxVel;
} else if (vel < -JointConfig[nr].MaxVel) {
vel = -JointConfig[nr].MaxVel;
}
emcmotCommand.joint = nr;
emcmotCommand.axis = -1; } else {
if (nr < 0 || nr >= EMCMOT_MAX_AXIS) { return 0; }
if (vel > AxisConfig[nr].MaxVel) {
vel = AxisConfig[nr].MaxVel;
} else if (vel < -AxisConfig[nr].MaxVel) {
vel = -AxisConfig[nr].MaxVel;
}
emcmotCommand.joint = -1; emcmotCommand.axis = nr;
}
emcmotCommand.command = EMCMOT_JOG_ABS;
emcmotCommand.vel = vel;
emcmotCommand.offset = pos;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcJogStop(int nr, int jjogmode)
{
if (jjogmode) {
if (nr < 0 || nr >= EMCMOT_MAX_JOINTS) { return 0; }
emcmotCommand.joint = nr;
emcmotCommand.axis = -1; } else {
if (nr < 0 || nr >= EMCMOT_MAX_AXIS) { return 0; }
emcmotCommand.joint = -1; emcmotCommand.axis = nr;
}
emcmotCommand.command = EMCMOT_JOINT_ABORT;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcJointLoadComp(int joint, const char *file, int type)
{
return usrmotLoadComp(joint, file, type);
}
static emcmot_config_t emcmotConfig;
int get_emcmot_debug_info = 0;
static emcmot_debug_t emcmotDebug;
static char errorString[EMCMOT_ERROR_LEN];
static int new_config = 0;
int emcJointUpdate(EMC_JOINT_STAT stat[], int numJoints)
{
int joint_num;
emcmot_joint_status_t *joint;
#ifdef WATCH_FLAGS
static int old_joint_flag[8];
#endif
if (numJoints <= 0 || numJoints > EMCMOT_MAX_JOINTS) {
return -1;
}
for (joint_num = 0; joint_num < numJoints; joint_num++) {
joint = &(emcmotStatus.joint_status[joint_num]);
stat[joint_num].jointType = JointConfig[joint_num].Type;
stat[joint_num].units = JointConfig[joint_num].Units;
if (new_config) {
stat[joint_num].backlash = joint->backlash;
stat[joint_num].minPositionLimit = joint->min_pos_limit;
stat[joint_num].maxPositionLimit = joint->max_pos_limit;
stat[joint_num].minFerror = joint->min_ferror;
stat[joint_num].maxFerror = joint->max_ferror;
}
stat[joint_num].output = joint->pos_cmd;
stat[joint_num].input = joint->pos_fb;
stat[joint_num].velocity = joint->vel_cmd;
stat[joint_num].ferrorCurrent = joint->ferror;
stat[joint_num].ferrorHighMark = joint->ferror_high_mark;
stat[joint_num].homing = joint->homing;
stat[joint_num].homed = joint->homed;
stat[joint_num].fault = (joint->flag & EMCMOT_JOINT_FAULT_BIT ? 1 : 0);
stat[joint_num].enabled = (joint->flag & EMCMOT_JOINT_ENABLE_BIT ? 1 : 0);
stat[joint_num].inpos = (joint->flag & EMCMOT_JOINT_INPOS_BIT ? 1 : 0);
stat[joint_num].minSoftLimit = 0;
stat[joint_num].maxSoftLimit = 0;
stat[joint_num].minHardLimit =
(joint->flag & EMCMOT_JOINT_MIN_HARD_LIMIT_BIT ? 1 : 0);
stat[joint_num].maxHardLimit =
(joint->flag & EMCMOT_JOINT_MAX_HARD_LIMIT_BIT ? 1 : 0);
stat[joint_num].overrideLimits = !!(emcmotStatus.overrideLimitMask);
#ifdef WATCH_FLAGS
if (old_joint_flag[joint_num] != joint->flag) {
printf("joint %d flag: %04X -> %04X\n", joint_num,
old_joint_flag[joint_num], joint->flag);
old_joint_flag[joint_num] = joint->flag;
}
#endif
if (joint->flag & EMCMOT_JOINT_ERROR_BIT) {
if (stat[joint_num].status != RCS_ERROR) {
rcs_print_error("Error on joint %d, command number %d\n",
joint_num, emcmotStatus.commandNumEcho);
stat[joint_num].status = RCS_ERROR;
}
} else if (joint->flag & EMCMOT_JOINT_INPOS_BIT) {
stat[joint_num].status = RCS_DONE;
} else {
stat[joint_num].status = RCS_EXEC;
}
}
return 0;
}
int emcTrajSetJoints(int joints)
{
if (joints <= 0 || joints > EMCMOT_MAX_JOINTS) {
rcs_print("emcTrajSetJoints failing: joints=%d\n",
joints);
return -1;
}
TrajConfig.Joints = joints;
emcmotCommand.command = EMCMOT_SET_NUM_JOINTS;
emcmotCommand.joint = joints;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d) returned %d\n", __FUNCTION__, joints, retval);
}
return retval;
}
int emcTrajSetAxes(int axismask)
{
int axes = 0;
for(int i=0; i<EMCMOT_MAX_AXIS; i++)
if(axismask & (1<<i)) axes = i+1;
TrajConfig.DeprecatedAxes = axes;
TrajConfig.AxisMask = axismask;
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d, %d)\n", __FUNCTION__, axes, axismask);
}
return 0;
}
int emcTrajSetSpindles(int spindles)
{
if (spindles <= 0 || spindles > EMCMOT_MAX_SPINDLES) {
rcs_print("emcTrajSetSpindles failing: spindles=%d\n",
spindles);
return -1;
}
TrajConfig.Spindles = spindles;
emcmotCommand.command = EMCMOT_SET_NUM_SPINDLES;
emcmotCommand.spindle = spindles;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%d) returned %d\n", __FUNCTION__, spindles, retval);
}
return retval;
}
int emcTrajSetUnits(double linearUnits, double angularUnits)
{
if (linearUnits <= 0.0 || angularUnits <= 0.0) {
return -1;
}
TrajConfig.LinearUnits = linearUnits;
TrajConfig.AngularUnits = angularUnits;
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%.4f, %.4f)\n", __FUNCTION__, linearUnits, angularUnits);
}
return 0;
}
int emcTrajSetMode(int mode)
{
switch (mode) {
case EMC_TRAJ_MODE_FREE:
emcmotCommand.command = EMCMOT_FREE;
return usrmotWriteEmcmotCommand(&emcmotCommand);
case EMC_TRAJ_MODE_COORD:
emcmotCommand.command = EMCMOT_COORD;
return usrmotWriteEmcmotCommand(&emcmotCommand);
case EMC_TRAJ_MODE_TELEOP:
emcmotCommand.command = EMCMOT_TELEOP;
return usrmotWriteEmcmotCommand(&emcmotCommand);
default:
return -1;
}
}
int emcTrajSetVelocity(double vel, double ini_maxvel)
{
if (vel < 0.0) {
vel = 0.0;
} else if (vel > TrajConfig.MaxVel) {
vel = TrajConfig.MaxVel;
}
if (ini_maxvel < 0.0) {
ini_maxvel = 0.0;
} else if (vel > TrajConfig.MaxVel) {
ini_maxvel = TrajConfig.MaxVel;
}
emcmotCommand.command = EMCMOT_SET_VEL;
emcmotCommand.vel = vel;
emcmotCommand.ini_maxvel = ini_maxvel;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%.4f, %.4f) returned %d\n", __FUNCTION__, vel, ini_maxvel, retval);
}
return retval;
}
int emcTrajSetAcceleration(double acc)
{
if (acc < 0.0) {
acc = 0.0;
} else if (acc > TrajConfig.MaxAccel) {
acc = TrajConfig.MaxAccel;
}
emcmotCommand.command = EMCMOT_SET_ACC;
emcmotCommand.acc = acc;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%.4f) returned %d\n", __FUNCTION__, acc, retval);
}
return retval;
}
int emcTrajSetMaxVelocity(double vel)
{
if (vel < 0.0) {
vel = 0.0;
}
TrajConfig.MaxVel = vel;
emcmotCommand.command = EMCMOT_SET_VEL_LIMIT;
emcmotCommand.vel = vel;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%.4f) returned %d\n", __FUNCTION__, vel, retval);
}
return retval;
}
int emcTrajSetMaxAcceleration(double acc)
{
if (acc < 0.0) {
acc = 0.0;
}
TrajConfig.MaxAccel = acc;
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%.4f)\n", __FUNCTION__, acc);
}
return 0;
}
int emcTrajSetHome(EmcPose home)
{
#ifdef ISNAN_TRAP
if (std::isnan(home.tran.x) || std::isnan(home.tran.y) || std::isnan(home.tran.z) ||
std::isnan(home.a) || std::isnan(home.b) || std::isnan(home.c) ||
std::isnan(home.u) || std::isnan(home.v) || std::isnan(home.w)) {
printf("std::isnan error in emcTrajSetHome()\n");
return 0; }
#endif
emcmotCommand.command = EMCMOT_SET_WORLD_HOME;
emcmotCommand.pos = home;
int retval = usrmotWriteEmcmotCommand(&emcmotCommand);
if (emc_debug & EMC_DEBUG_CONFIG) {
rcs_print("%s(%.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f) returned %d\n",
__FUNCTION__, home.tran.x, home.tran.y, home.tran.z, home.a, home.b, home.c,
home.u, home.v, home.w, retval);
}
return retval;
}
int emcTrajSetScale(double scale)
{
if (scale < 0.0) {
scale = 0.0;
}
emcmotCommand.command = EMCMOT_FEED_SCALE;
emcmotCommand.scale = scale;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajSetRapidScale(double scale)
{
if (scale < 0.0) {
scale = 0.0;
}
emcmotCommand.command = EMCMOT_RAPID_SCALE;
emcmotCommand.scale = scale;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajSetSpindleScale(int spindle, double scale)
{
if (scale < 0.0) {
scale = 0.0;
}
emcmotCommand.command = EMCMOT_SPINDLE_SCALE;
emcmotCommand.scale = scale;
emcmotCommand.spindle = spindle;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajSetFOEnable(unsigned char mode)
{
emcmotCommand.command = EMCMOT_FS_ENABLE;
emcmotCommand.mode = mode;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajSetFHEnable(unsigned char mode)
{
emcmotCommand.command = EMCMOT_FH_ENABLE;
emcmotCommand.mode = mode;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajSetSOEnable(unsigned char mode)
{
emcmotCommand.command = EMCMOT_SS_ENABLE;
emcmotCommand.mode = mode;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajSetAFEnable(unsigned char enable)
{
emcmotCommand.command = EMCMOT_AF_ENABLE;
if ( enable ) {
emcmotCommand.flags = 1;
} else {
emcmotCommand.flags = 0;
}
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajSetMotionId(int id)
{
if (EMC_DEBUG_MOTION_TIME & emc_debug) {
if (id != TrajConfig.MotionId) {
rcs_print("Outgoing motion id is %d.\n", id);
}
}
TrajConfig.MotionId = id;
return 0;
}
int emcTrajInit()
{
int retval = 0;
TrajConfig.Inited = 0;
TrajConfig.Joints = 0;
TrajConfig.MaxAccel = DBL_MAX;
TrajConfig.DeprecatedAxes = 0;
TrajConfig.AxisMask = 0;
TrajConfig.LinearUnits = 1.0;
TrajConfig.AngularUnits = 1.0;
TrajConfig.MotionId = 0;
TrajConfig.MaxVel = DEFAULT_TRAJ_MAX_VELOCITY;
if (!JointOrTrajInited()) {
usrmotIniLoad(emc_inifile);
if (0 != usrmotInit("emc2_task")) {
return -1;
}
}
TrajConfig.Inited = 1;
if (0 != iniTraj(emc_inifile)) {
retval = -1;
}
return retval;
}
int emcTrajHalt()
{
TrajConfig.Inited = 0;
if (!JointOrTrajInited()) {
usrmotExit(); }
return 0;
}
int emcTrajEnable()
{
emcmotCommand.command = EMCMOT_ENABLE;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajDisable()
{
emcmotCommand.command = EMCMOT_DISABLE;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajAbort()
{
emcmotCommand.command = EMCMOT_ABORT;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajPause()
{
emcmotCommand.command = EMCMOT_PAUSE;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajReverse()
{
emcmotCommand.command = EMCMOT_REVERSE;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajForward()
{
emcmotCommand.command = EMCMOT_FORWARD;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajStep()
{
emcmotCommand.command = EMCMOT_STEP;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajResume()
{
emcmotCommand.command = EMCMOT_RESUME;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajDelay(double delay)
{
return 0;
}
double emcTrajGetLinearUnits()
{
return TrajConfig.LinearUnits;
}
double emcTrajGetAngularUnits()
{
return TrajConfig.AngularUnits;
}
int emcTrajSetOffset(EmcPose tool_offset)
{
emcmotCommand.command = EMCMOT_SET_OFFSET;
emcmotCommand.tool_offset = tool_offset;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajSetSpindleSync(int spindle, double fpr, bool wait_for_index)
{
emcmotCommand.command = EMCMOT_SET_SPINDLESYNC;
emcmotCommand.spindle = spindle;
emcmotCommand.spindlesync = fpr;
emcmotCommand.flags = wait_for_index;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajSetTermCond(int cond, double tolerance)
{
emcmotCommand.command = EMCMOT_SET_TERM_COND;
emcmotCommand.termCond = cond;
emcmotCommand.tolerance = tolerance;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajLinearMove(EmcPose end, int type, double vel, double ini_maxvel, double acc,
int indexer_jnum)
{
#ifdef ISNAN_TRAP
if (std::isnan(end.tran.x) || std::isnan(end.tran.y) || std::isnan(end.tran.z) ||
std::isnan(end.a) || std::isnan(end.b) || std::isnan(end.c) ||
std::isnan(end.u) || std::isnan(end.v) || std::isnan(end.w)) {
printf("std::isnan error in emcTrajLinearMove()\n");
return 0; }
#endif
emcmotCommand.command = EMCMOT_SET_LINE;
emcmotCommand.pos = end;
emcmotCommand.id = TrajConfig.MotionId;
emcmotCommand.motion_type = type;
emcmotCommand.vel = vel;
emcmotCommand.ini_maxvel = ini_maxvel;
emcmotCommand.acc = acc;
emcmotCommand.turn = indexer_jnum;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajCircularMove(EmcPose end, PM_CARTESIAN center,
PM_CARTESIAN normal, int turn, int type, double vel, double ini_maxvel, double acc)
{
#ifdef ISNAN_TRAP
if (std::isnan(end.tran.x) || std::isnan(end.tran.y) || std::isnan(end.tran.z) ||
std::isnan(end.a) || std::isnan(end.b) || std::isnan(end.c) ||
std::isnan(end.u) || std::isnan(end.v) || std::isnan(end.w) ||
std::isnan(center.x) || std::isnan(center.y) || std::isnan(center.z) ||
std::isnan(normal.x) || std::isnan(normal.y) || std::isnan(normal.z)) {
printf("std::isnan error in emcTrajCircularMove()\n");
return 0; }
#endif
emcmotCommand.command = EMCMOT_SET_CIRCLE;
emcmotCommand.pos = end;
emcmotCommand.motion_type = type;
emcmotCommand.center.x = center.x;
emcmotCommand.center.y = center.y;
emcmotCommand.center.z = center.z;
emcmotCommand.normal.x = normal.x;
emcmotCommand.normal.y = normal.y;
emcmotCommand.normal.z = normal.z;
emcmotCommand.turn = turn;
emcmotCommand.id = TrajConfig.MotionId;
emcmotCommand.vel = vel;
emcmotCommand.ini_maxvel = ini_maxvel;
emcmotCommand.acc = acc;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajClearProbeTrippedFlag()
{
emcmotCommand.command = EMCMOT_CLEAR_PROBE_FLAGS;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajProbe(EmcPose pos, int type, double vel, double ini_maxvel, double acc, unsigned char probe_type)
{
#ifdef ISNAN_TRAP
if (std::isnan(pos.tran.x) || std::isnan(pos.tran.y) || std::isnan(pos.tran.z) ||
std::isnan(pos.a) || std::isnan(pos.b) || std::isnan(pos.c) ||
std::isnan(pos.u) || std::isnan(pos.v) || std::isnan(pos.w)) {
printf("std::isnan error in emcTrajProbe()\n");
return 0; }
#endif
emcmotCommand.command = EMCMOT_PROBE;
emcmotCommand.pos = pos;
emcmotCommand.id = TrajConfig.MotionId;
emcmotCommand.motion_type = type;
emcmotCommand.vel = vel;
emcmotCommand.ini_maxvel = ini_maxvel;
emcmotCommand.acc = acc;
emcmotCommand.probe_type = probe_type;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcTrajRigidTap(EmcPose pos, double vel, double ini_maxvel, double acc, double scale)
{
#ifdef ISNAN_TRAP
if (std::isnan(pos.tran.x) || std::isnan(pos.tran.y) || std::isnan(pos.tran.z)) {
printf("std::isnan error in emcTrajRigidTap()\n");
return 0; }
#endif
emcmotCommand.command = EMCMOT_RIGID_TAP;
emcmotCommand.pos.tran = pos.tran;
emcmotCommand.id = TrajConfig.MotionId;
emcmotCommand.vel = vel;
emcmotCommand.ini_maxvel = ini_maxvel;
emcmotCommand.acc = acc;
emcmotCommand.scale = scale;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
static int last_id = 0;
static int last_id_printed = 0;
static int last_status = 0;
static double last_id_time;
int emcTrajUpdate(EMC_TRAJ_STAT * stat)
{
int joint, enables;
stat->joints = TrajConfig.Joints;
stat->spindles = TrajConfig.Spindles;
stat->deprecated_axes = TrajConfig.DeprecatedAxes;
stat->axis_mask = TrajConfig.AxisMask;
stat->linearUnits = TrajConfig.LinearUnits;
stat->angularUnits = TrajConfig.AngularUnits;
stat->mode =
emcmotStatus.
motionFlag & EMCMOT_MOTION_TELEOP_BIT ? EMC_TRAJ_MODE_TELEOP
: (emcmotStatus.
motionFlag & EMCMOT_MOTION_COORD_BIT ? EMC_TRAJ_MODE_COORD :
EMC_TRAJ_MODE_FREE);
stat->enabled = 0;
if (emcmotStatus.motionFlag & EMCMOT_MOTION_ENABLE_BIT) {
for (joint = 0; joint < TrajConfig.Joints; joint++) {
#if 0#endif
stat->enabled = 1;
}
}
stat->inpos = emcmotStatus.motionFlag & EMCMOT_MOTION_INPOS_BIT;
stat->queue = emcmotStatus.depth;
stat->activeQueue = emcmotStatus.activeDepth;
stat->queueFull = emcmotStatus.queueFull;
stat->id = emcmotStatus.id;
stat->motion_type = emcmotStatus.motionType;
stat->distance_to_go = emcmotStatus.distance_to_go;
stat->dtg = emcmotStatus.dtg;
stat->current_vel = emcmotStatus.current_vel;
if (EMC_DEBUG_MOTION_TIME & emc_debug) {
if (stat->id != last_id) {
if (last_id != last_id_printed) {
rcs_print("Motion id %d took %f seconds.\n", last_id,
etime() - last_id_time);
last_id_printed = last_id;
}
last_id = stat->id;
last_id_time = etime();
}
}
stat->paused = emcmotStatus.paused;
stat->scale = emcmotStatus.feed_scale;
stat->rapid_scale = emcmotStatus.rapid_scale;
stat->position = emcmotStatus.carte_pos_cmd;
stat->actualPosition = emcmotStatus.carte_pos_fb;
stat->velocity = emcmotStatus.vel;
stat->acceleration = emcmotStatus.acc;
stat->maxAcceleration = TrajConfig.MaxAccel;
if (emcmotStatus.motionFlag & EMCMOT_MOTION_ERROR_BIT) {
stat->status = RCS_ERROR;
} else if (stat->inpos && (stat->queue == 0)) {
stat->status = RCS_DONE;
} else {
stat->status = RCS_EXEC;
}
if (EMC_DEBUG_MOTION_TIME & emc_debug) {
if (stat->status == RCS_DONE && last_status != RCS_DONE
&& stat->id != last_id_printed) {
rcs_print("Motion id %d took %f seconds.\n", last_id,
etime() - last_id_time);
last_id_printed = last_id = stat->id;
last_id_time = etime();
}
}
stat->probedPosition = emcmotStatus.probedPos;
stat->probeval = emcmotStatus.probeVal;
stat->probing = emcmotStatus.probing;
stat->probe_tripped = emcmotStatus.probeTripped;
if (emcmotStatus.motionFlag & EMCMOT_MOTION_COORD_BIT)
enables = emcmotStatus.enables_queued;
else
enables = emcmotStatus.enables_new;
stat->feed_override_enabled = enables & FS_ENABLED;
stat->adaptive_feed_enabled = enables & AF_ENABLED;
stat->feed_hold_enabled = enables & FH_ENABLED;
if (new_config) {
stat->cycleTime = emcmotConfig.trajCycleTime;
stat->kinematics_type = emcmotConfig.kinType;
stat->maxVelocity = emcmotConfig.limitVel;
}
return 0;
}
int setup_inihal(void) {
if (emcmotion_initialized != 1) {
rcs_print_error("%s: emcMotionInit() has not completed, can't setup inihal\n", __FUNCTION__);
return -1;
}
if (ini_hal_init(TrajConfig.Joints)) {
rcs_print_error("%s: ini_hal_init(%d) failed\n", __FUNCTION__, TrajConfig.Joints);
return -1;
}
if (ini_hal_init_pins(TrajConfig.Joints)) {
rcs_print_error("%s: ini_hal_init_pins(%d) failed\n", __FUNCTION__, TrajConfig.Joints);
return -1;
}
return 0;
}
int emcPositionLoad() {
double positions[EMCMOT_MAX_JOINTS];
IniFile ini;
ini.Open(emc_inifile);
const char *posfile = ini.Find("POSITION_FILE", "TRAJ");
ini.Close();
if(!posfile || !posfile[0]) return 0;
FILE *f = fopen(posfile, "r");
if(!f) return 0;
for(int i=0; i<EMCMOT_MAX_JOINTS; i++) {
int r = fscanf(f, "%lf", &positions[i]);
if(r != 1) {
fclose(f);
rcs_print("%s: failed to load joint %d position from %s, ignoring\n", __FUNCTION__, i, posfile);
return -1;
}
}
fclose(f);
int result = 0;
for(int i=0; i<EMCMOT_MAX_JOINTS; i++) {
if(emcJointSetMotorOffset(i, -positions[i]) != 0) {
rcs_print("%s: failed to set joint %d position (%.6f) from %s, ignoring\n", __FUNCTION__, i, positions[i], posfile);
result = -1;
}
}
return result;
}
int emcPositionSave() {
IniFile ini;
const char *posfile;
ini.Open(emc_inifile);
try {
posfile = ini.Find("POSITION_FILE", "TRAJ");
} catch (IniFile::Exception e) {
ini.Close();
return -1;
}
ini.Close();
if(!posfile || !posfile[0]) return 0;
unlink(posfile);
FILE *f = fopen(posfile, "w");
if(!f) return -1;
for(int i=0; i<EMCMOT_MAX_JOINTS; i++) {
int r = fprintf(f, "%.17f\n", emcmotStatus.joint_status[i].pos_fb);
if(r < 0) { fclose(f); return -1; }
}
fclose(f);
return 0;
}
int emcMotionInit()
{
int r;
int joint, axis;
r = emcTrajInit(); if (r != 0) {
rcs_print("%s: emcTrajInit failed\n", __FUNCTION__);
return -1;
}
for (joint = 0; joint < TrajConfig.Joints; joint++) {
if (0 != emcJointInit(joint)) {
rcs_print("%s: emcJointInit(%d) failed\n", __FUNCTION__, joint);
return -1;
}
}
for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
if (TrajConfig.AxisMask & (1<<axis)) {
if (0 != emcAxisInit(axis)) {
rcs_print("%s: emcAxisInit(%d) failed\n", __FUNCTION__, axis);
return -1;
}
}
}
(void)emcPositionLoad();
emcmotion_initialized = 1;
return 0;
}
int emcMotionHalt()
{
int r1, r2, r3, r4, r5;
int t;
r1 = -1;
for (t = 0; t < EMCMOT_MAX_JOINTS; t++) {
if (0 == emcJointHalt(t)) {
r1 = 0; }
}
r2 = emcTrajDisable();
r3 = emcTrajHalt();
r4 = emcPositionSave();
r5 = ini_hal_exit();
emcmotion_initialized = 0;
return (r1 == 0 && r2 == 0 && r3 == 0 && r4 == 0 && r5 == 0) ? 0 : -1;
}
int emcMotionAbort()
{
int r1;
int r2;
int r3 = 0;
int t;
r1 = -1;
for (t = 0; t < EMCMOT_MAX_JOINTS; t++) {
if (0 == emcJointAbort(t)) {
r1 = 0; }
}
r2 = emcTrajAbort();
return (r1 == 0 && r2 == 0 && r3 == 0) ? 0 : -1;
}
int emcMotionSetDebug(int debug)
{
emcmotCommand.command = EMCMOT_SET_DEBUG;
emcmotCommand.debug = debug;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcMotionSetAout(unsigned char index, double start, double end, unsigned char now)
{
emcmotCommand.command = EMCMOT_SET_AOUT;
emcmotCommand.now = now;
emcmotCommand.out = index;
emcmotCommand.minLimit = start;
emcmotCommand.maxLimit = end;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcMotionSetDout(unsigned char index, unsigned char start,
unsigned char end, unsigned char now)
{
emcmotCommand.command = EMCMOT_SET_DOUT;
emcmotCommand.now = now;
emcmotCommand.out = index;
emcmotCommand.start = start;
emcmotCommand.end = end;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcSpindleAbort(int spindle)
{
return emcSpindleOff(spindle);
}
int emcSpindleSpeed(int spindle, double speed, double css_factor, double offset)
{
if (emcmotStatus.spindle_status[spindle].speed == 0){
return 0;}
return emcSpindleOn(spindle, speed, css_factor, offset);
}
int emcSpindleOrient(int spindle, double orientation, int mode)
{
emcmotCommand.command = EMCMOT_SPINDLE_ORIENT;
emcmotCommand.spindle = spindle;
emcmotCommand.orientation = orientation;
emcmotCommand.mode = mode;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcSpindleOn(int spindle, double speed, double css_factor, double offset, int wait_for_at_speed)
{
emcmotCommand.command = EMCMOT_SPINDLE_ON;
emcmotCommand.spindle = spindle;
emcmotCommand.vel = speed;
emcmotCommand.ini_maxvel = css_factor;
emcmotCommand.acc = offset;
emcmotCommand.wait_for_spindle_at_speed = wait_for_at_speed;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcSpindleOff(int spindle)
{
emcmotCommand.command = EMCMOT_SPINDLE_OFF;
emcmotCommand.spindle = spindle;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcSpindleBrakeRelease(int spindle)
{
emcmotCommand.command = EMCMOT_SPINDLE_BRAKE_RELEASE;
emcmotCommand.spindle = spindle;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcSpindleBrakeEngage(int spindle)
{
emcmotCommand.command = EMCMOT_SPINDLE_BRAKE_ENGAGE;
emcmotCommand.spindle = spindle;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcSpindleIncrease(int spindle)
{
emcmotCommand.command = EMCMOT_SPINDLE_INCREASE;
emcmotCommand.spindle = spindle;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcSpindleDecrease(int spindle)
{
emcmotCommand.command = EMCMOT_SPINDLE_DECREASE;
emcmotCommand.spindle = spindle;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcSpindleConstant(int spindle)
{
return 0; }
int emcSpindleUpdate(EMC_SPINDLE_STAT stat[], int num_spindles){
int s;
int enables;
if (emcmotStatus.motionFlag & EMCMOT_MOTION_COORD_BIT)
enables = emcmotStatus.enables_queued;
else
enables = emcmotStatus.enables_new;
for (s = 0; s < num_spindles; s++){
stat[s].spindle_override_enabled = enables & SS_ENABLED;
stat[s].enabled = emcmotStatus.spindle_status[s].speed != 0;
stat[s].speed = emcmotStatus.spindle_status[s].speed;
stat[s].brake = emcmotStatus.spindle_status[s].brake;
stat[s].direction = emcmotStatus.spindle_status[s].direction;
stat[s].orient_state = emcmotStatus.spindle_status[s].orient_state;
stat[s].orient_fault = emcmotStatus.spindle_status[s].orient_fault;
stat[s].spindle_scale = emcmotStatus.spindle_status[s].scale;
}
return 0;
}
int emcMotionUpdate(EMC_MOTION_STAT * stat)
{
int r1, r2, r3, r4;
int joint;
int error;
int exec;
int dio, aio;
if (0 != usrmotReadEmcmotStatus(&emcmotStatus)) {
return -1;
}
new_config = 0;
if (emcmotStatus.config_num != emcmotConfig.config_num) {
if (0 != usrmotReadEmcmotConfig(&emcmotConfig)) {
return -1;
}
new_config = 1;
}
if (get_emcmot_debug_info) {
if (0 != usrmotReadEmcmotDebug(&emcmotDebug)) {
return -1;
}
}
if (0 != usrmotReadEmcmotError(errorString)) {
} else {
emcOperatorError(0, "%s", errorString);
}
localMotionHeartbeat = emcmotStatus.heartbeat;
localMotionCommandType = emcmotStatus.commandEcho;
localMotionEchoSerialNumber = emcmotStatus.commandNumEcho;
r3 = emcTrajUpdate(&stat->traj);
r1 = emcJointUpdate(&stat->joint[0], stat->traj.joints);
r2 = emcAxisUpdate(&stat->axis[0], stat->traj.axis_mask);
r3 = emcTrajUpdate(&stat->traj);
r4 = emcSpindleUpdate(&stat->spindle[0], stat->traj.spindles);
stat->heartbeat = localMotionHeartbeat;
stat->command_type = localMotionCommandType;
stat->echo_serial_number = localMotionEchoSerialNumber;
stat->debug = emcmotConfig.debug;
for (dio = 0; dio < EMCMOT_MAX_DIO; dio++) {
stat->synch_di[dio] = emcmotStatus.synch_di[dio];
stat->synch_do[dio] = emcmotStatus.synch_do[dio];
}
for (aio = 0; aio < EMCMOT_MAX_AIO; aio++) {
stat->analog_input[aio] = emcmotStatus.analog_input[aio];
stat->analog_output[aio] = emcmotStatus.analog_output[aio];
}
stat->numExtraJoints=emcmotStatus.numExtraJoints;
error = 0;
exec = 0;
for (joint = 0; joint < stat->traj.joints; joint++) {
if (stat->joint[joint].status == RCS_ERROR) {
error = 1;
break;
}
if (stat->joint[joint].status == RCS_EXEC) {
exec = 1;
break;
}
}
if (stat->traj.status == RCS_ERROR) {
error = 1;
} else if (stat->traj.status == RCS_EXEC) {
exec = 1;
}
if (error) {
stat->status = RCS_ERROR;
} else if (exec) {
stat->status = RCS_EXEC;
} else {
stat->status = RCS_DONE;
}
return (r1 == 0 && r2 == 0 && r3 == 0 && r4 == 0) ? 0 : -1;
}
int emcSetupArcBlends(int arcBlendEnable,
int arcBlendFallbackEnable,
int arcBlendOptDepth,
int arcBlendGapCycles,
double arcBlendRampFreq,
double arcBlendTangentKinkRatio) {
emcmotCommand.command = EMCMOT_SETUP_ARC_BLENDS;
emcmotCommand.arcBlendEnable = arcBlendEnable;
emcmotCommand.arcBlendFallbackEnable = arcBlendFallbackEnable;
emcmotCommand.arcBlendOptDepth = arcBlendOptDepth;
emcmotCommand.arcBlendGapCycles = arcBlendGapCycles;
emcmotCommand.arcBlendRampFreq = arcBlendRampFreq;
emcmotCommand.arcBlendTangentKinkRatio = arcBlendTangentKinkRatio;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcSetMaxFeedOverride(double maxFeedScale) {
emcmotCommand.command = EMCMOT_SET_MAX_FEED_OVERRIDE;
emcmotCommand.maxFeedScale = maxFeedScale;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcSetProbeErrorInhibit(int j_inhibit, int h_inhibit) {
emcmotCommand.command = EMCMOT_SET_PROBE_ERR_INHIBIT;
emcmotCommand.probe_jog_err_inhibit = j_inhibit;
emcmotCommand.probe_home_err_inhibit = h_inhibit;
return usrmotWriteEmcmotCommand(&emcmotCommand);
}
int emcGetExternalOffsetApplied(void) {
return emcmotStatus.external_offsets_applied;
}
EmcPose emcGetExternalOffsets(void) {
return emcmotStatus.eoffset_pose;
}