#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <math.h>
#include <tcl.h>
#include <tk.h>
#include "rcs.hh"
#include "posemath.h"
#include "emc.hh"
#include "emc_nml.hh"
#include "canon.hh"
#include "emcglb.h"
#include "emccfg.h"
#include "inifile.hh"
#include "rcs_print.hh"
#include "timer.hh"
#include "shcom.hh"
#define setresult(t,s) Tcl_SetObjResult((t), Tcl_NewStringObj((s),-1))
#define CHECKEMC \
if (!checkStatus() ) {\
setresult(interp,"emc not connected");\
return TCL_ERROR;\
}
static void thisQuit(ClientData clientData)
{
EMC_NULL emc_null_msg;
if (0 != emcStatusBuffer) {
emcCommandWaitReceived();
}
if (emcErrorBuffer != 0) {
delete emcErrorBuffer;
emcErrorBuffer = 0;
}
if (emcStatusBuffer != 0) {
delete emcStatusBuffer;
emcStatusBuffer = 0;
emcStatus = 0;
}
if (emcCommandBuffer != 0) {
delete emcCommandBuffer;
emcCommandBuffer = 0;
}
return;
}
static int emc_plat(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
if (objc == 1) {
setresult(interp,"Linux");
return TCL_OK;
}
setresult(interp,"emc_plat: need no args");
return TCL_ERROR;
}
static int emc_ini(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
IniFile inifile;
const char *inistring;
const char *varstr, *secstr, *defaultstr;
defaultstr = 0;
if (objc != 3 && objc != 4) {
setresult(interp,"emc_ini: need 'var' and 'section'");
return TCL_ERROR;
}
if (inifile.Open(emc_inifile) == false) {
return TCL_OK;
}
varstr = Tcl_GetStringFromObj(objv[1], 0);
secstr = Tcl_GetStringFromObj(objv[2], 0);
if (objc == 4) {
defaultstr = Tcl_GetStringFromObj(objv[3], 0);
}
if (NULL == (inistring = inifile.Find(varstr, secstr))) {
if (defaultstr != 0) {
setresult(interp,(char *) defaultstr);
}
return TCL_OK;
}
setresult(interp,(char *) inistring);
inifile.Close();
return TCL_OK;
}
static int emc_Debug(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
Tcl_Obj *debug_obj;
int debug;
CHECKEMC
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
if (objc == 1) {
debug_obj = Tcl_NewIntObj(emcStatus->debug);
Tcl_SetObjResult(interp, debug_obj);
return TCL_OK;
}
if (objc == 2) {
if (0 != Tcl_GetIntFromObj(0, objv[1], &debug)) {
setresult(interp,"emc_debug: need debug level as integer");
return TCL_ERROR;
}
sendDebug(debug);
emc_debug = debug;
return TCL_OK;
}
setresult(interp,"emc_debug: need zero or one arg");
return TCL_ERROR;
}
static int emc_set_wait(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
char *objstr;
CHECKEMC
if (objc == 1) {
switch (emcWaitType) {
case EMC_WAIT_RECEIVED:
setresult(interp,"received");
break;
case EMC_WAIT_DONE:
setresult(interp,"done");
break;
default:
setresult(interp,"(invalid)");
break;
}
return TCL_OK;
}
if (objc == 2) {
objstr = Tcl_GetStringFromObj(objv[1], 0);
if (!strcmp(objstr, "received")) {
emcWaitType = EMC_WAIT_RECEIVED;
return TCL_OK;
}
if (!strcmp(objstr, "done")) {
emcWaitType = EMC_WAIT_DONE;
return TCL_OK;
}
}
setresult(interp, "emc_set_wait: need 'received', 'done', or no args");
return TCL_ERROR;
}
static int emc_wait(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
char *objstr;
CHECKEMC
if (objc == 2) {
objstr = Tcl_GetStringFromObj(objv[1], 0);
if (!strcmp(objstr, "received")) {
if (0 != emcCommandWaitReceived()) {
setresult(interp,"timeout");
}
return TCL_OK;
}
if (!strcmp(objstr, "done")) {
if (0 != emcCommandWaitDone()) {
setresult(interp,"timeout");
}
return TCL_OK;
}
}
setresult(interp,"emc_wait: need 'received' or 'done'");
return TCL_ERROR;
}
static int emc_set_timeout(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
double timeout;
Tcl_Obj *timeout_obj;
CHECKEMC
if (objc == 1) {
timeout_obj = Tcl_NewDoubleObj(emcTimeout);
Tcl_SetObjResult(interp, timeout_obj);
return TCL_OK;
}
if (objc == 2) {
if (TCL_OK == Tcl_GetDoubleFromObj(0, objv[1], &timeout)) {
emcTimeout = timeout;
return TCL_OK;
}
}
setresult(interp,"emc_set_timeout: need time as real number");
return TCL_ERROR;
}
static int emc_update(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
char *objstr;
CHECKEMC
if (objc == 1) {
updateStatus();
return TCL_OK;
}
if (objc == 2) {
objstr = Tcl_GetStringFromObj(objv[1], 0);
if (!strcmp(objstr, "none")) {
emcUpdateType = EMC_UPDATE_NONE;
return TCL_OK;
}
if (!strcmp(objstr, "auto")) {
emcUpdateType = EMC_UPDATE_AUTO;
return TCL_OK;
}
}
return TCL_OK;
}
static int emc_time(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
CHECKEMC
if (objc == 1) {
Tcl_SetObjResult(interp, Tcl_NewDoubleObj(etime()));
return TCL_OK;
}
setresult(interp,"emc_time: needs no arguments");
return TCL_ERROR;
}
static int emc_error(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
CHECKEMC
if (objc == 1) {
if (0 != updateError()) {
setresult(interp,"emc_error: bad status from EMC");
return TCL_ERROR;
}
if (error_string[0] == 0) {
setresult(interp,"ok");
} else {
setresult(interp,error_string);
error_string[0] = 0;
}
return TCL_OK;
}
setresult(interp,"emc_error: need no args");
return TCL_ERROR;
}
static int emc_operator_text(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
CHECKEMC
if (objc == 1) {
if (0 != updateError()) {
setresult(interp,"emc_operator_text: bad status from EMC");
return TCL_ERROR;
}
if (operator_text_string[0] == 0) {
setresult(interp,"ok");
operator_text_string[0] = 0;
} else {
setresult(interp,operator_text_string);
}
return TCL_OK;
}
setresult(interp,"emc_operator_text: need no args");
return TCL_ERROR;
}
static int emc_operator_display(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
CHECKEMC
if (objc == 1) {
if (0 != updateError()) {
setresult(interp,"emc_operator_display: bad status from EMC");
return TCL_ERROR;
}
if (operator_display_string[0] == 0) {
setresult(interp,"ok");
} else {
setresult(interp,operator_display_string);
operator_display_string[0] = 0;
}
return TCL_OK;
}
setresult(interp,"emc_operator_display: need no args");
return TCL_ERROR;
}
static int emc_estop(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
char *objstr;
CHECKEMC
if (objc == 1) {
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
if (emcStatus->task.state == EMC_TASK_STATE_ESTOP) {
setresult(interp,"on");
} else {
setresult(interp,"off");
}
return TCL_OK;
}
if (objc == 2) {
objstr = Tcl_GetStringFromObj(objv[1], 0);
if (!strcmp(objstr, "on")) {
sendEstop();
return TCL_OK;
}
if (!strcmp(objstr, "off")) {
sendEstopReset();
return TCL_OK;
}
}
setresult(interp, "emc_estop: need 'on', 'off', or no args");
return TCL_ERROR;
}
static int emc_machine(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
char *objstr;
CHECKEMC
if (objc == 1) {
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
if (emcStatus->task.state == EMC_TASK_STATE_ON) {
setresult(interp,"on");
} else {
setresult(interp,"off");
}
return TCL_OK;
}
if (objc == 2) {
objstr = Tcl_GetStringFromObj(objv[1], 0);
if (!strcmp(objstr, "on")) {
sendMachineOn();
return TCL_OK;
}
if (!strcmp(objstr, "off")) {
sendMachineOff();
return TCL_OK;
}
}
setresult(interp, "emc_machine: need 'on', 'off', or no args");
return TCL_ERROR;
}
static int emc_mode(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
char *objstr;
CHECKEMC
if (objc == 1) {
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
switch (emcStatus->task.mode) {
case EMC_TASK_MODE_MANUAL:
setresult(interp,"manual");
break;
case EMC_TASK_MODE_AUTO:
setresult(interp,"auto");
break;
case EMC_TASK_MODE_MDI:
setresult(interp,"mdi");
break;
default:
setresult(interp,"?");
break;
}
return TCL_OK;
}
if (objc == 2) {
objstr = Tcl_GetStringFromObj(objv[1], 0);
if (!strcmp(objstr, "manual")) {
sendManual();
return TCL_OK;
}
if (!strcmp(objstr, "auto")) {
sendAuto();
return TCL_OK;
}
if (!strcmp(objstr, "mdi")) {
sendMdi();
return TCL_OK;
}
}
setresult(interp,"emc_mode: need 'manual', 'auto', 'mdi', or no args");
return TCL_ERROR;
}
static int emc_mist(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
char *objstr;
CHECKEMC
if (objc == 1) {
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
if (emcStatus->io.coolant.mist == 1) {
setresult(interp,"on");
} else {
setresult(interp,"off");
}
return TCL_OK;
}
if (objc == 2) {
objstr = Tcl_GetStringFromObj(objv[1], 0);
if (!strcmp(objstr, "on")) {
sendMistOn();
return TCL_OK;
}
if (!strcmp(objstr, "off")) {
sendMistOff();
return TCL_OK;
}
}
setresult(interp,"emc_mist: need 'on', 'off', or no args");
return TCL_ERROR;
}
static int emc_flood(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
char *objstr;
CHECKEMC
if (objc == 1) {
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
if (emcStatus->io.coolant.flood == 1) {
setresult(interp,"on");
} else {
setresult(interp,"off");
}
return TCL_OK;
}
if (objc == 2) {
objstr = Tcl_GetStringFromObj(objv[1], 0);
if (!strcmp(objstr, "on")) {
sendFloodOn();
return TCL_OK;
}
if (!strcmp(objstr, "off")) {
sendFloodOff();
return TCL_OK;
}
}
setresult(interp,"emc_flood: need 'on', 'off', or no args"); return TCL_ERROR;
}
static int emc_lube(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
char *objstr;
CHECKEMC
if (objc == 1) {
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
if (emcStatus->io.lube.on == 0) {
setresult(interp,"off");
} else {
setresult(interp,"on");
}
return TCL_OK;
}
if (objc == 2) {
objstr = Tcl_GetStringFromObj(objv[1], 0);
if (!strcmp(objstr, "on")) {
sendLubeOn();
return TCL_OK;
}
if (!strcmp(objstr, "off")) {
sendLubeOff();
return TCL_OK;
}
}
setresult(interp,"emc_lube: need 'on', 'off', or no args");
return TCL_ERROR;
}
static int emc_lube_level(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
CHECKEMC
if (objc == 1) {
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
if (emcStatus->io.lube.level == 0) {
setresult(interp,"low");
} else {
setresult(interp,"ok");
}
return TCL_OK;
}
setresult(interp,"emc_lube_level: need no args");
return TCL_ERROR;
}
static int emc_spindle(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
char *objstr = NULL;
int spindle = 0;
CHECKEMC
if (objc >= 2) {
if (Tcl_GetIntFromObj(interp, objv[1], &spindle) != TCL_OK){ spindle = 0;
objstr = Tcl_GetStringFromObj(objv[1], 0);
} else {
if (spindle < 0 || spindle > EMCMOT_MAX_SPINDLES){ setresult(interp,"invalid spindle index number");
return TCL_ERROR;
}
objstr = Tcl_GetStringFromObj(objv[2], 0);
}
}
if (objstr) {
if (!strcmp(objstr, "forward")) {
sendSpindleForward(spindle);
return TCL_OK;
}
if (!strcmp(objstr, "reverse")) {
sendSpindleReverse(spindle);
return TCL_OK;
}
if (!strcmp(objstr, "increase")) {
sendSpindleIncrease(spindle);
return TCL_OK;
}
if (!strcmp(objstr, "decrease")) {
sendSpindleDecrease(spindle);
return TCL_OK;
}
if (!strcmp(objstr, "constant")) {
sendSpindleConstant(spindle);
return TCL_OK;
}
if (!strcmp(objstr, "off")) {
sendSpindleOff(spindle);
return TCL_OK;
}
}
else
{
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
if (emcStatus->motion.spindle[spindle].increasing > 0) {
setresult(interp,"increase");
} else if (emcStatus->motion.spindle[spindle].increasing < 0) {
setresult(interp,"decrease");
} else if (emcStatus->motion.spindle[spindle].direction > 0) {
setresult(interp,"forward");
} else if (emcStatus->motion.spindle[spindle].direction < 0) {
setresult(interp,"reverse");
} else {
setresult(interp,"off");
}
return TCL_OK;
}
setresult(interp,"emc_spindle: need 'on', 'off', a spindle index or no args");
return TCL_ERROR;
}
static int emc_brake(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
char *objstr = NULL;
int spindle = 0;
CHECKEMC
if (objc >= 2) {
if (Tcl_GetIntFromObj(interp, objv[1], &spindle) != TCL_OK){ spindle = 0;
objstr = Tcl_GetStringFromObj(objv[1], 0);
} else {
if (spindle < 0 || spindle > EMCMOT_MAX_SPINDLES){ setresult(interp,"invalid spindle index number");
return TCL_ERROR;
}
objstr = Tcl_GetStringFromObj(objv[2], 0);
}
}
if (objstr) {
if (!strcmp(objstr, "on")) {
sendBrakeEngage(spindle);
return TCL_OK;
}
if (!strcmp(objstr, "off")) {
sendBrakeRelease(spindle);
return TCL_OK;
}
}
else
{
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
if (emcStatus->motion.spindle[spindle].brake == 1) {
setresult(interp,"on");
} else {
setresult(interp,"off");
}
return TCL_OK;
}
setresult(interp,"emc_brake: need 'on', 'off', spindle index or no args");
return TCL_ERROR;
}
static int emc_tool(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
Tcl_Obj *toolobj;
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_tool: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
toolobj = Tcl_NewIntObj(emcStatus->io.tool.toolInSpindle);
Tcl_SetObjResult(interp, toolobj);
return TCL_OK;
}
static int emc_tool_offset(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
char string[1];
Tcl_Obj *tlobj;
string[0] = 'Z';
CHECKEMC
if (objc > 2) {
setresult(interp,"emc_tool_offset: need 0 or 1 args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
if (objc != 1) {
strncpy(string, Tcl_GetStringFromObj(objv[1], 0),1);
}
switch (string[0]) {
case 'x': case 'X':
tlobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->task.toolOffset.tran.x));
break;
case 'y': case 'Y':
tlobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->task.toolOffset.tran.y));
break;
case 'z': case 'Z':
tlobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->task.toolOffset.tran.z));
break;
case 'a': case 'A':
tlobj = Tcl_NewDoubleObj(convertAngularUnits(
emcStatus->task.toolOffset.a));
break;
case 'b': case 'B':
tlobj = Tcl_NewDoubleObj(convertAngularUnits(
emcStatus->task.toolOffset.b));
break;
case 'c': case 'C':
tlobj = Tcl_NewDoubleObj(convertAngularUnits(
emcStatus->task.toolOffset.c));
break;
case 'u': case 'U':
tlobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->task.toolOffset.u));
break;
case 'v': case 'V':
tlobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->task.toolOffset.v));
break;
case 'w': case 'W':
tlobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->task.toolOffset.w));
break;
default:
setresult(interp,"emc_tool_offset: bad coordinate letter argument");
return TCL_ERROR;
}
Tcl_SetObjResult(interp, tlobj);
return TCL_OK;
}
static int emc_load_tool_table(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
CHECKEMC
if (objc != 2) {
setresult(interp,"emc_load_tool_table: need file");
return TCL_ERROR;
}
if (0 != sendLoadToolTable(Tcl_GetStringFromObj(objv[1], 0))) {
setresult(interp,"emc_load_tool_table: can't open file");
return TCL_OK;
}
return TCL_OK;
}
static int emc_set_tool_offset(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
int tool;
double length;
double diameter;
CHECKEMC
if (objc != 4) {
setresult(interp,"emc_set_tool_offset: need <tool> <length> <diameter>");
return TCL_ERROR;
}
if (0 != Tcl_GetIntFromObj(0, objv[1], &tool)) {
setresult(interp,"emc_set_tool_offset: need tool as integer, 0..");
return TCL_ERROR;
}
if (0 != Tcl_GetDoubleFromObj(0, objv[2], &length)) {
setresult(interp,"emc_set_tool_offset: need length as real number");
return TCL_ERROR;
}
if (0 != Tcl_GetDoubleFromObj(0, objv[3], &diameter)) {
setresult(interp,"emc_set_tool_offset: need diameter as real number");
return TCL_ERROR;
}
if (0 != sendToolSetOffset(tool, length, diameter)) {
setresult(interp,"emc_set_tool_offset: can't set it");
return TCL_OK;
}
return TCL_OK;
}
static int emc_abs_cmd_pos(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
char string[1];
Tcl_Obj *posobj;
CHECKEMC
if (objc != 2) {
setresult(interp,"emc_abs_cmd_pos: need exactly 1 coordinate letter");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
strncpy(string, Tcl_GetStringFromObj(objv[1], 0),1);
switch (string[0]) {
case 'x': case 'X':
posobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->motion.traj.position.tran.x));
break;
case 'y': case 'Y':
posobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->motion.traj.position.tran.y));
break;
case 'z': case 'Z':
posobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->motion.traj.position.tran.z));
break;
case 'a': case 'A':
posobj = Tcl_NewDoubleObj(convertAngularUnits(
emcStatus->motion.traj.position.a));
break;
case 'b': case 'B':
posobj = Tcl_NewDoubleObj(convertAngularUnits(
emcStatus->motion.traj.position.b));
break;
case 'c': case 'C':
posobj = Tcl_NewDoubleObj(convertAngularUnits(
emcStatus->motion.traj.position.c));
break;
case 'u': case 'U':
posobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->motion.traj.position.u));
break;
case 'v': case 'V':
posobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->motion.traj.position.v));
break;
case 'w': case 'W':
posobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->motion.traj.position.w));
break;
default:
setresult(interp,"emc_abs_cmd_pos: bad coordinate letter argument");
return TCL_ERROR;
}
Tcl_SetObjResult(interp, posobj);
return TCL_OK;
}
static int emc_abs_act_pos(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
char string[1];
Tcl_Obj *posobj;
CHECKEMC
if (objc != 2) {
setresult(interp,"emc_abs_act_pos: need exactly 1 non-negative integer");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
strncpy(string, Tcl_GetStringFromObj(objv[1], 0),1);
switch (string[0]) {
case 'x': case 'X':
posobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->motion.traj.actualPosition.tran.x));
break;
case 'y': case 'Y':
posobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->motion.traj.actualPosition.tran.y));
break;
case 'z': case 'Z':
posobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->motion.traj.actualPosition.tran.z));
break;
case 'a': case 'A':
posobj = Tcl_NewDoubleObj(convertAngularUnits(
emcStatus->motion.traj.actualPosition.a));
break;
case 'b': case 'B':
posobj = Tcl_NewDoubleObj(convertAngularUnits(
emcStatus->motion.traj.actualPosition.b));
break;
case 'c': case 'C':
posobj = Tcl_NewDoubleObj(convertAngularUnits(
emcStatus->motion.traj.actualPosition.c));
break;
case 'u': case 'U':
posobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->motion.traj.actualPosition.u));
break;
case 'v': case 'V':
posobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->motion.traj.actualPosition.v));
break;
case 'w': case 'W':
posobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->motion.traj.actualPosition.w));
break;
default:
setresult(interp,"emc_abs_act_pos: bad coordinate letter argument");
return TCL_ERROR;
}
Tcl_SetObjResult(interp, posobj);
return TCL_OK;
}
static int emc_rel_cmd_pos(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
char string[1];
Tcl_Obj *posobj;
CHECKEMC
if (objc != 2) {
setresult(interp,"emc_rel_cmd_pos: need exactly 1 non-negative integer");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
strncpy(string, Tcl_GetStringFromObj(objv[1], 0),1);
double d = 0.0;
switch (string[0]) {
case 'x': case 'X':
d = convertLinearUnits(emcStatus->motion.traj.position.tran.x -
emcStatus->task.g5x_offset.tran.x -
emcStatus->task.g92_offset.tran.x -
emcStatus->task.toolOffset.tran.x);
break;
case 'y': case 'Y':
d = convertLinearUnits(emcStatus->motion.traj.position.tran.y -
emcStatus->task.g5x_offset.tran.y -
emcStatus->task.g92_offset.tran.y -
emcStatus->task.toolOffset.tran.y);
break;
case 'z': case 'Z':
d = convertLinearUnits(emcStatus->motion.traj.position.tran.z -
emcStatus->task.g5x_offset.tran.z -
emcStatus->task.g92_offset.tran.z -
emcStatus->task.toolOffset.tran.z);
break;
case 'a': case 'A':
d = convertAngularUnits(emcStatus->motion.traj.position.a -
emcStatus->task.g5x_offset.a -
emcStatus->task.g92_offset.a -
emcStatus->task.toolOffset.a);
break;
case 'b': case 'B':
d = convertAngularUnits(emcStatus->motion.traj.position.b -
emcStatus->task.g5x_offset.b -
emcStatus->task.g92_offset.b -
emcStatus->task.toolOffset.b);
break;
case 'c': case 'C':
d = convertAngularUnits(emcStatus->motion.traj.position.c -
emcStatus->task.g5x_offset.c -
emcStatus->task.g92_offset.c -
emcStatus->task.toolOffset.c);
break;
case 'u': case 'U':
d = convertLinearUnits(emcStatus->motion.traj.position.u -
emcStatus->task.g5x_offset.u -
emcStatus->task.g92_offset.u -
emcStatus->task.toolOffset.u);
break;
case 'v': case 'V':
d = convertLinearUnits(emcStatus->motion.traj.position.v -
emcStatus->task.g5x_offset.v -
emcStatus->task.g92_offset.v -
emcStatus->task.toolOffset.v);
break;
case 'w': case 'W':
d = convertLinearUnits(emcStatus->motion.traj.position.w -
emcStatus->task.g5x_offset.w -
emcStatus->task.g92_offset.w -
emcStatus->task.toolOffset.w);
break;
default:
setresult(interp,"emc_rel_cmd_pos: bad coordinate letter argument");
return TCL_ERROR;
}
posobj = Tcl_NewDoubleObj(d);
Tcl_SetObjResult(interp, posobj);
return TCL_OK;
}
static int emc_rel_act_pos(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
char string[1];
Tcl_Obj *posobj;
CHECKEMC
if (objc != 2) {
setresult(interp,"emc_rel_act_pos: need exactly 1 non-negative integer");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
strncpy(string, Tcl_GetStringFromObj(objv[1], 0),1);
double d = 0.0;
switch (string[0]) {
case 'x': case 'X':
d = convertLinearUnits(emcStatus->motion.traj.actualPosition.tran.x -
emcStatus->task.g5x_offset.tran.x -
emcStatus->task.g92_offset.tran.x -
emcStatus->task.toolOffset.tran.x);
break;
case 'y': case 'Y':
d = convertLinearUnits(emcStatus->motion.traj.actualPosition.tran.y -
emcStatus->task.g5x_offset.tran.y -
emcStatus->task.g92_offset.tran.y -
emcStatus->task.toolOffset.tran.y);
break;
case 'z': case 'Z':
d = convertLinearUnits(emcStatus->motion.traj.actualPosition.tran.z -
emcStatus->task.g5x_offset.tran.z -
emcStatus->task.g92_offset.tran.z -
emcStatus->task.toolOffset.tran.z);
break;
case 'a': case 'A':
d = convertAngularUnits(emcStatus->motion.traj.actualPosition.a -
emcStatus->task.g5x_offset.a -
emcStatus->task.g92_offset.a -
emcStatus->task.toolOffset.a);
break;
case 'b': case 'B':
d = convertAngularUnits(emcStatus->motion.traj.actualPosition.b -
emcStatus->task.g5x_offset.b -
emcStatus->task.g92_offset.b -
emcStatus->task.toolOffset.b);
break;
case 'c': case 'C':
d = convertAngularUnits(emcStatus->motion.traj.actualPosition.c -
emcStatus->task.g5x_offset.c -
emcStatus->task.g92_offset.c -
emcStatus->task.toolOffset.c);
break;
case 'u': case 'U':
d = convertLinearUnits(emcStatus->motion.traj.actualPosition.u -
emcStatus->task.g5x_offset.u -
emcStatus->task.g92_offset.u -
emcStatus->task.toolOffset.u);
break;
case 'v': case 'V':
d = convertLinearUnits(emcStatus->motion.traj.actualPosition.v -
emcStatus->task.g5x_offset.v -
emcStatus->task.g92_offset.v -
emcStatus->task.toolOffset.v);
break;
case 'w': case 'W':
d = convertLinearUnits(emcStatus->motion.traj.actualPosition.w -
emcStatus->task.g5x_offset.w -
emcStatus->task.g92_offset.w -
emcStatus->task.toolOffset.w);
break;
default:
setresult(interp,"emc_rel_act_pos: bad coordinate letter argument");
return TCL_ERROR;
}
posobj = Tcl_NewDoubleObj(d);
Tcl_SetObjResult(interp, posobj);
return TCL_OK;
}
static int emc_joint_pos(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
int joint;
Tcl_Obj *posobj;
CHECKEMC
if (objc != 2) {
setresult(interp,"emc_joint_pos: need exactly 1 non-negative integer");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
if (TCL_OK == Tcl_GetIntFromObj(0, objv[1], &joint)) {
posobj = Tcl_NewDoubleObj(emcStatus->motion.joint[joint].input);
} else {
setresult(interp,"emc_joint_pos: bad integer argument");
return TCL_ERROR;
}
Tcl_SetObjResult(interp, posobj);
return TCL_OK;
}
static int emc_pos_offset(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
char string[1];
Tcl_Obj *posobj;
CHECKEMC
if (objc != 2) {
setresult(interp,"emc_pos_offset: need exactly 1 coordinate letter");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
strncpy(string, Tcl_GetStringFromObj(objv[1], 0),1);
switch (string[0]) {
case 'x': case 'X':
posobj = Tcl_NewDoubleObj(convertLinearUnits(emcStatus->task.g5x_offset.tran.x
+emcStatus->task.g92_offset.tran.x));
break;
case 'y': case 'Y':
posobj = Tcl_NewDoubleObj(convertLinearUnits(emcStatus->task.g5x_offset.tran.y
+emcStatus->task.g92_offset.tran.y));
break;
case 'z': case 'Z':
posobj = Tcl_NewDoubleObj(convertLinearUnits(emcStatus->task.g5x_offset.tran.z
+emcStatus->task.g92_offset.tran.z));
break;
case 'a': case 'A':
posobj = Tcl_NewDoubleObj(convertAngularUnits(emcStatus->task.g5x_offset.a
+emcStatus->task.g92_offset.a));
break;
case 'b': case 'B':
posobj = Tcl_NewDoubleObj(convertAngularUnits(emcStatus->task.g5x_offset.b
+emcStatus->task.g92_offset.b));
break;
case 'c': case 'C':
posobj = Tcl_NewDoubleObj(convertAngularUnits(emcStatus->task.g5x_offset.c
+emcStatus->task.g92_offset.c));
break;
case 'u': case 'U':
posobj = Tcl_NewDoubleObj(convertLinearUnits(emcStatus->task.g5x_offset.u
+emcStatus->task.g92_offset.u));
break;
case 'v': case 'V':
posobj = Tcl_NewDoubleObj(convertLinearUnits(emcStatus->task.g5x_offset.v
+emcStatus->task.g92_offset.v));
break;
case 'w': case 'W':
posobj = Tcl_NewDoubleObj(convertLinearUnits(emcStatus->task.g5x_offset.w
+emcStatus->task.g92_offset.w));
break;
default:
setresult(interp,"emc_pos_offset: bad coordinate letter argument");
return TCL_ERROR;
}
Tcl_SetObjResult(interp, posobj);
return TCL_OK;
}
static int emc_joint_limit(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
int joint;
CHECKEMC
if (objc != 2) {
setresult(interp,"emc_joint_limit: need exactly 1 non-negative integer");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
if (TCL_OK == Tcl_GetIntFromObj(0, objv[1], &joint)) {
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
setresult(interp,"emc_joint_limit: joint out of bounds");
return TCL_ERROR;
}
if (emcStatus->motion.joint[joint].minHardLimit) {
setresult(interp,"minhard");
return TCL_OK;
} else if (emcStatus->motion.joint[joint].minSoftLimit) {
setresult(interp,"minsoft");
return TCL_OK;
} else if (emcStatus->motion.joint[joint].maxSoftLimit) {
setresult(interp,"maxsoft");
return TCL_OK;
} else if (emcStatus->motion.joint[joint].maxHardLimit) {
setresult(interp,"maxsoft");
return TCL_OK;
} else {
setresult(interp,"ok");
return TCL_OK;
}
}
setresult(interp,"emc_joint_limit: joint out of bounds");
return TCL_ERROR;
}
static int emc_joint_fault(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
int joint;
CHECKEMC
if (objc != 2) {
setresult(interp,"emc_joint_fault: need exactly 1 non-negative integer");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
if (TCL_OK == Tcl_GetIntFromObj(0, objv[1], &joint)) {
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
setresult(interp,"emc_joint_fault: joint out of bounds");
return TCL_ERROR;
}
if (emcStatus->motion.joint[joint].fault) {
setresult(interp,"fault");
return TCL_OK;
} else {
setresult(interp,"ok");
return TCL_OK;
}
}
setresult(interp,"emc_joint_fault: joint out of bounds");
return TCL_ERROR;
}
static int emc_override_limit(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
Tcl_Obj *obj;
int on;
CHECKEMC
if (objc == 1) {
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
obj = Tcl_NewIntObj(emcStatus->motion.joint[0].overrideLimits);
Tcl_SetObjResult(interp, obj);
return TCL_OK;
}
if (objc == 2) {
if (TCL_OK == Tcl_GetIntFromObj(0, objv[1], &on)) {
if (on) {
if (0 != sendOverrideLimits(0)) {
setresult(interp,"emc_override_limit: can't send command");
return TCL_OK;
}
} else {
if (0 != sendOverrideLimits(-1)) {
setresult(interp,"emc_override_limit: can't send command");
return TCL_OK;
}
}
return TCL_OK;
} else {
setresult(interp,"emc_override_limit: need 0 or 1");
return TCL_ERROR;
}
}
setresult(interp,"emc_override_limit: need no args, 0 or 1");
return TCL_ERROR;
}
static int emc_joint_homed(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
int joint;
CHECKEMC
if (objc != 2) {
setresult(interp,"emc_joint_homed: need exactly 1 non-negative integer");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
if (TCL_OK == Tcl_GetIntFromObj(0, objv[1], &joint)) {
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
setresult(interp,"emc_joint_homed: joint out of bounds");
return TCL_ERROR;
}
if (emcStatus->motion.joint[joint].homed) {
setresult(interp,"homed");
return TCL_OK;
} else {
setresult(interp,"not");
return TCL_OK;
}
}
setresult(interp,"emc_joint_homed: joint out of bounds");
return TCL_ERROR;
}
static int emc_mdi(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
char string[256];
int t;
CHECKEMC
if (objc < 2) {
setresult(interp,"emc_mdi: need command");
return TCL_ERROR;
}
strcpy(string, Tcl_GetStringFromObj(objv[1], 0));
for (t = 2; t < objc; t++) {
strcat(string, " ");
strcat(string, Tcl_GetStringFromObj(objv[t], 0));
}
if (0 != sendMdiCmd(string)) {
setresult(interp,"emc_mdi: error executing command");
return TCL_OK;
}
return TCL_OK;
}
static int emc_home(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
int joint;
CHECKEMC
if (objc != 2) {
setresult(interp,"emc_home: need joint");
return TCL_ERROR;
}
if (TCL_OK == Tcl_GetIntFromObj(0, objv[1], &joint)) {
sendHome(joint);
return TCL_OK;
}
setresult(interp,"emc_home: need joint as integer, 0..");
return TCL_ERROR;
}
static int emc_unhome(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
int joint;
CHECKEMC
if (objc != 2) {
setresult(interp,"emc_unhome: need joint");
return TCL_ERROR;
}
if (TCL_OK == Tcl_GetIntFromObj(0, objv[1], &joint)) {
sendUnHome(joint);
return TCL_OK;
}
setresult(interp,"emc_unhome: need joint as integer, 0..");
return TCL_ERROR;
}
static int emc_jog_stop(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
int joint;
int jjogmode;
CHECKEMC
if (objc != 3) {
setresult(interp,"emc_jog_stop: need joint,jogmode");
return TCL_ERROR;
}
if (0 != Tcl_GetIntFromObj(0, objv[1], &joint)) {
setresult(interp,"emc_jog_stop: need joint as integer, 0|1");
return TCL_ERROR;
}
if (0 != Tcl_GetIntFromObj(0, objv[2], &jjogmode)) {
setresult(interp,"emc_jog_stop: need jogmode as integer, 0..");
return TCL_ERROR;
}
if (0 != sendJogStop(joint, jjogmode)) {
setresult(interp,"emc_jog_stop: can't send jog stop msg");
return TCL_OK;
}
return TCL_OK;
}
static int emc_jog(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
int joint;
int jjogmode;
double speed;
CHECKEMC
if (objc != 4) {
setresult(interp,"emc_jog: need joint,jjogmode and speed");
return TCL_ERROR;
}
if (0 != Tcl_GetIntFromObj(0, objv[1], &joint)) {
setresult(interp,"emc_jog: need joint as integer, 0|1");
return TCL_ERROR;
}
if (0 != Tcl_GetIntFromObj(0, objv[2], &jjogmode)) {
setresult(interp,"emc_jog: need jogmode as integer, 0..");
return TCL_ERROR;
}
if (0 != Tcl_GetDoubleFromObj(0, objv[3], &speed)) {
setresult(interp,"emc_jog: need speed as real number");
return TCL_ERROR;
}
if (0 != sendJogCont(joint, jjogmode, speed)) {
setresult(interp,"emc_jog: can't jog");
return TCL_OK;
}
return TCL_OK;
}
static int emc_jog_incr(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
int joint;
int jjogmode;
double speed;
double incr;
CHECKEMC
if (objc != 5) {
setresult(interp,"emc_jog_incr: need jjogmode,joint, speed, and increment");
return TCL_ERROR;
}
if (0 != Tcl_GetIntFromObj(0, objv[1], &joint)) {
setresult(interp,"emc_jog_incr: need joint as integer, 0|1");
return TCL_ERROR;
}
if (0 != Tcl_GetIntFromObj(0, objv[2], &jjogmode)) {
setresult(interp,"emc_jog_incr: need jogmode as integer, 0..");
return TCL_ERROR;
}
if (0 != Tcl_GetDoubleFromObj(0, objv[3], &speed)) {
setresult(interp,"emc_jog_incr: need speed as real number");
return TCL_ERROR;
}
if (0 != Tcl_GetDoubleFromObj(0, objv[4], &incr)) {
setresult(interp,"emc_jog_incr: need increment as real number");
return TCL_ERROR;
}
if (0 != sendJogIncr(joint, jjogmode, speed, incr)) {
setresult(interp,"emc_jog_incr: can't jog");
return TCL_OK;
}
return TCL_OK;
}
static int emc_feed_override(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
Tcl_Obj *feedobj;
int percent;
CHECKEMC
if (objc == 1) {
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
feedobj =
Tcl_NewIntObj((int)
(emcStatus->motion.traj.scale * 100.0 + 0.5));
Tcl_SetObjResult(interp, feedobj);
return TCL_OK;
}
if (objc != 2) {
setresult(interp,"emc_feed_override: need percent");
return TCL_ERROR;
}
if (TCL_OK == Tcl_GetIntFromObj(0, objv[1], &percent)) {
sendFeedOverride(((double) percent) / 100.0);
return TCL_OK;
}
setresult(interp,"emc_feed_override: need percent");
return TCL_ERROR;
}
static int emc_rapid_override(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
Tcl_Obj *rapidobj;
int percent;
CHECKEMC
if (objc == 1) {
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
rapidobj =
Tcl_NewIntObj((int)
(emcStatus->motion.traj.rapid_scale * 100.0 + 0.5));
Tcl_SetObjResult(interp, rapidobj);
return TCL_OK;
}
if (objc != 2) {
setresult(interp,"emc_rapid_override: need percent");
return TCL_ERROR;
}
if (TCL_OK == Tcl_GetIntFromObj(0, objv[1], &percent)) {
sendRapidOverride(((double) percent) / 100.0);
return TCL_OK;
}
setresult(interp,"emc_rapid_override: need percent");
return TCL_ERROR;
}
static int emc_spindle_override(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
Tcl_Obj *feedobj;
int spindle = 0;
int percent;
CHECKEMC
if (objc == 1) {
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
feedobj = Tcl_NewIntObj((int)(emcStatus->motion.spindle[spindle].spindle_scale * 100.0 + 0.5));
Tcl_SetObjResult(interp, feedobj);
return TCL_OK;
}
if (objc == 2){
if (TCL_OK == Tcl_GetIntFromObj(0, objv[1], &percent)) {
sendSpindleOverride(spindle, ((double) percent) / 100.0);
return TCL_OK;
}
}
if (objc == 3){ if (TCL_OK != Tcl_GetIntFromObj(0, objv[1], &spindle)) {
setresult(interp,"emc_spindle_override: malformed spindle number");
return TCL_ERROR;
}
if (TCL_OK != Tcl_GetIntFromObj(0, objv[2], &percent)) {
setresult(interp,"emc_spindle_override: need percent");
return TCL_ERROR;
}
sendSpindleOverride(spindle, ((double) percent) / 100.0);
return TCL_OK;
}
setresult(interp,"emc_spindle_override: need percent");
return TCL_ERROR;
}
static int emc_task_plan_init(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
CHECKEMC
if (0 != sendTaskPlanInit()) {
setresult(interp,"emc_task_plan_init: can't init interpreter");
return TCL_OK;
}
return TCL_OK;
}
static int emc_open(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
CHECKEMC
if (objc != 2) {
setresult(interp,"emc_open: need file");
return TCL_ERROR;
}
if (0 != sendProgramOpen(Tcl_GetStringFromObj(objv[1], 0))) {
setresult(interp,"emc_open: can't open file");
return TCL_OK;
}
return TCL_OK;
}
static int emc_run(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
int line;
CHECKEMC
if (objc == 1) {
if (0 != sendProgramRun(0)) {
setresult(interp,"emc_run: can't execute program");
return TCL_OK;
}
}
if (objc == 2) {
if (0 != Tcl_GetIntFromObj(0, objv[1], &line)) {
setresult(interp,"emc_run: need integer start line");
return TCL_ERROR;
}
if (0 != sendProgramRun(line)) {
setresult(interp,"emc_run: can't execute program");
return TCL_OK;
}
}
return TCL_OK;
}
static int emc_pause(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
CHECKEMC
if (0 != sendProgramPause()) {
setresult(interp,"emc_pause: can't pause program");
return TCL_OK;
}
return TCL_OK;
}
static int emc_optional_stop(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
Tcl_Obj *obj;
int on;
CHECKEMC
if (objc == 1) {
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
obj = Tcl_NewIntObj(emcStatus->task.optional_stop_state);
Tcl_SetObjResult(interp, obj);
return TCL_OK;
}
if (objc == 2) {
if (TCL_OK == Tcl_GetIntFromObj(0, objv[1], &on)) {
if (0 != sendSetOptionalStop(on)) {
setresult(interp,"emc_optional_stop: can't send command");
return TCL_OK;
}
return TCL_OK;
} else {
setresult(interp,"emc_optional_stop: need 0 or 1");
return TCL_ERROR;
}
}
setresult(interp,"emc_optional_stop: need no args, 0 or 1");
return TCL_ERROR;
}
static int emc_resume(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
CHECKEMC
if (0 != sendProgramResume()) {
setresult(interp,"emc_resume: can't resume program");
return TCL_OK;
}
return TCL_OK;
}
static int emc_step(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
CHECKEMC
if (0 != sendProgramStep()) {
setresult(interp,"emc_step: can't step program");
return TCL_OK;
}
return TCL_OK;
}
static int emc_abort(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
CHECKEMC
if (0 != sendAbort()) {
setresult(interp,"emc_abort: can't execute program");
return TCL_OK;
}
return TCL_OK;
}
static int emc_program(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_program: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
if (0 != emcStatus->task.file[0]) {
setresult(interp,emcStatus->task.file);
return TCL_OK;
}
setresult(interp,"none");
return TCL_OK;
}
static int emc_program_status(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_program_status: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
switch (emcStatus->task.interpState) {
case EMC_TASK_INTERP_READING:
case EMC_TASK_INTERP_WAITING:
setresult(interp,"running");
return TCL_OK;
break;
case EMC_TASK_INTERP_PAUSED:
setresult(interp,"paused");
return TCL_OK;
break;
default:
setresult(interp,"idle");
return TCL_OK;
}
setresult(interp,"idle");
return TCL_OK;
}
static int emc_program_line(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
Tcl_Obj *lineobj;
int programActiveLine = 0;
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_program_line: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
if (programStartLine < 0
|| emcStatus->task.readLine < programStartLine) {
programActiveLine = emcStatus->task.readLine;
} else { if (emcStatus->task.currentLine > 0) {
if (emcStatus->task.motionLine > 0 &&
emcStatus->task.motionLine < emcStatus->task.currentLine) {
programActiveLine = emcStatus->task.motionLine;
} else {
programActiveLine = emcStatus->task.currentLine;
}
} else {
programActiveLine = 0;
}
}
lineobj = Tcl_NewIntObj(programActiveLine);
Tcl_SetObjResult(interp, lineobj);
return TCL_OK;
}
static int emc_program_codes(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
char codes_string[256];
char string[256];
int t;
int code;
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_program_codes: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
codes_string[0] = 0;
for (t = 1; t < ACTIVE_G_CODES; t++) {
code = emcStatus->task.activeGCodes[t];
if (code == -1) {
continue;
}
if (code % 10) {
sprintf(string, "G%.1f ", (double) code / 10.0);
} else {
sprintf(string, "G%d ", code / 10);
}
strcat(codes_string, string);
}
for (t = 1; t < ACTIVE_M_CODES; t++) {
code = emcStatus->task.activeMCodes[t];
if (code == -1) {
continue;
}
sprintf(string, "M%d ", code);
strcat(codes_string, string);
}
sprintf(string, "F%.0f ", emcStatus->task.activeSettings[1]);
strcat(codes_string, string);
sprintf(string, "S%.0f", fabs(emcStatus->task.activeSettings[2]));
strcat(codes_string, string);
setresult(interp,codes_string);
return TCL_OK;
}
static int emc_joint_type(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
int joint;
CHECKEMC
if (objc != 2) {
setresult(interp,"emc_joint_type: need exactly 1 non-negative integer");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
if (TCL_OK == Tcl_GetIntFromObj(0, objv[1], &joint)) {
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
setresult(interp,"emc_joint_type: joint out of bounds");
return TCL_ERROR;
}
switch (emcStatus->motion.joint[joint].jointType) {
case EMC_LINEAR:
setresult(interp,"linear");
break;
case EMC_ANGULAR:
setresult(interp,"angular");
break;
default:
setresult(interp,"custom");
break;
}
return TCL_OK;
}
setresult(interp,"emc_joint_type: invalid joint number");
return TCL_ERROR;
}
static int emc_joint_units(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
int joint;
CHECKEMC
if (objc != 2) {
setresult(interp,"emc_joint_units: need exactly 1 non-negative integer");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
if (TCL_OK == Tcl_GetIntFromObj(0, objv[1], &joint)) {
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
setresult(interp,"emc_joint_units: joint out of bounds");
return TCL_ERROR;
}
switch (emcStatus->motion.joint[joint].jointType) {
case EMC_LINEAR:
if (CLOSE(emcStatus->motion.joint[joint].units, 1.0,
LINEAR_CLOSENESS)) {
setresult(interp,"mm");
return TCL_OK;
}
else if (CLOSE
(emcStatus->motion.joint[joint].units, INCH_PER_MM,
LINEAR_CLOSENESS)) {
setresult(interp,"inch");
return TCL_OK;
}
else if (CLOSE(emcStatus->motion.joint[joint].units, CM_PER_MM,
LINEAR_CLOSENESS)) {
setresult(interp,"cm");
return TCL_OK;
}
setresult(interp,"custom");
return TCL_OK;
break;
case EMC_ANGULAR:
if (CLOSE(emcStatus->motion.joint[joint].units, 1.0,
ANGULAR_CLOSENESS)) {
setresult(interp,"deg");
return TCL_OK;
}
else if (CLOSE
(emcStatus->motion.joint[joint].units, RAD_PER_DEG,
ANGULAR_CLOSENESS)) {
setresult(interp,"rad");
return TCL_OK;
}
else if (CLOSE
(emcStatus->motion.joint[joint].units, GRAD_PER_DEG,
ANGULAR_CLOSENESS)) {
setresult(interp,"grad");
return TCL_OK;
}
setresult(interp,"custom");
return TCL_OK;
break;
default:
setresult(interp,"custom");
return TCL_OK;
break;
}
}
setresult(interp,"emc_joint_units: invalid joint number");
return TCL_ERROR;
}
static int emc_program_linear_units(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_program_linear_units: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
switch (emcStatus->task.programUnits) {
case CANON_UNITS_INCHES:
setresult(interp,"inch");
return TCL_OK;
break;
case CANON_UNITS_MM:
setresult(interp,"mm");
return TCL_OK;
break;
case CANON_UNITS_CM:
setresult(interp,"cm");
return TCL_OK;
break;
default:
setresult(interp,"custom");
return TCL_OK;
break;
}
setresult(interp,"custom");
return TCL_OK;
}
static int emc_program_angular_units(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_program_angular_units: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
setresult(interp,"deg");
return TCL_OK;
}
static int emc_user_linear_units(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_user_linear_units: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
if (CLOSE(emcStatus->motion.traj.linearUnits, 1.0, LINEAR_CLOSENESS)) {
setresult(interp,"mm");
return TCL_OK;
}
else if (CLOSE(emcStatus->motion.traj.linearUnits, INCH_PER_MM,
LINEAR_CLOSENESS)) {
setresult(interp,"inch");
return TCL_OK;
}
else if (CLOSE(emcStatus->motion.traj.linearUnits, CM_PER_MM,
LINEAR_CLOSENESS)) {
setresult(interp,"cm");
return TCL_OK;
}
setresult(interp,"custom");
return TCL_OK;
}
static int emc_user_angular_units(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_user_angular_units: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
if (CLOSE(emcStatus->motion.traj.angularUnits, 1.0, ANGULAR_CLOSENESS)) {
setresult(interp,"deg");
return TCL_OK;
}
else if (CLOSE(emcStatus->motion.traj.angularUnits, RAD_PER_DEG,
ANGULAR_CLOSENESS)) {
setresult(interp,"rad");
return TCL_OK;
}
else if (CLOSE(emcStatus->motion.traj.angularUnits, GRAD_PER_DEG,
ANGULAR_CLOSENESS)) {
setresult(interp,"grad");
return TCL_OK;
}
setresult(interp,"custom");
return TCL_OK;
}
static int emc_display_linear_units(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_display_linear_units: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
switch (linearUnitConversion) {
case LINEAR_UNITS_INCH:
setresult(interp,"inch");
break;
case LINEAR_UNITS_MM:
setresult(interp,"mm");
break;
case LINEAR_UNITS_CM:
setresult(interp,"cm");
break;
case LINEAR_UNITS_AUTO:
switch (emcStatus->task.programUnits) {
case CANON_UNITS_MM:
setresult(interp,"(mm)");
break;
case CANON_UNITS_INCHES:
setresult(interp,"(inch)");
break;
case CANON_UNITS_CM:
setresult(interp,"(cm)");
break;
}
break;
default:
setresult(interp,"custom");
break;
}
return TCL_OK;
}
static int emc_display_angular_units(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_display_angular_units: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
switch (angularUnitConversion) {
case ANGULAR_UNITS_DEG:
setresult(interp,"deg");
break;
case ANGULAR_UNITS_RAD:
setresult(interp,"rad");
break;
case ANGULAR_UNITS_GRAD:
setresult(interp,"grad");
break;
case ANGULAR_UNITS_AUTO:
setresult(interp,"(deg)");
break;
default:
setresult(interp,"custom");
break;
}
return TCL_OK;
}
static int emc_linear_unit_conversion(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
char *objstr;
CHECKEMC
if (objc == 1) {
switch (linearUnitConversion) {
case LINEAR_UNITS_INCH:
setresult(interp,"inch");
break;
case LINEAR_UNITS_MM:
setresult(interp,"mm");
break;
case LINEAR_UNITS_CM:
setresult(interp,"cm");
break;
case LINEAR_UNITS_AUTO:
setresult(interp,"auto");
break;
default:
setresult(interp,"custom");
break;
}
return TCL_OK;
}
if (objc == 2) {
objstr = Tcl_GetStringFromObj(objv[1], 0);
if (!strcmp(objstr, "inch")) {
linearUnitConversion = LINEAR_UNITS_INCH;
return TCL_OK;
}
if (!strcmp(objstr, "mm")) {
linearUnitConversion = LINEAR_UNITS_MM;
return TCL_OK;
}
if (!strcmp(objstr, "cm")) {
linearUnitConversion = LINEAR_UNITS_CM;
return TCL_OK;
}
if (!strcmp(objstr, "auto")) {
linearUnitConversion = LINEAR_UNITS_AUTO;
return TCL_OK;
}
if (!strcmp(objstr, "custom")) {
linearUnitConversion = LINEAR_UNITS_CUSTOM;
return TCL_OK;
}
}
setresult(interp,"emc_linear_unit_conversion: need 'inch', 'mm', 'cm', 'auto', 'custom', or no args");
return TCL_ERROR;
}
static int emc_angular_unit_conversion(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
char *objstr;
CHECKEMC
if (objc == 1) {
switch (angularUnitConversion) {
case ANGULAR_UNITS_DEG:
setresult(interp,"deg");
break;
case ANGULAR_UNITS_RAD:
setresult(interp,"rad");
break;
case ANGULAR_UNITS_GRAD:
setresult(interp,"grad");
break;
case ANGULAR_UNITS_AUTO:
setresult(interp,"auto");
break;
default:
setresult(interp,"custom");
break;
}
return TCL_OK;
}
if (objc == 2) {
objstr = Tcl_GetStringFromObj(objv[1], 0);
if (!strcmp(objstr, "deg")) {
angularUnitConversion = ANGULAR_UNITS_DEG;
return TCL_OK;
}
if (!strcmp(objstr, "rad")) {
angularUnitConversion = ANGULAR_UNITS_RAD;
return TCL_OK;
}
if (!strcmp(objstr, "grad")) {
angularUnitConversion = ANGULAR_UNITS_GRAD;
return TCL_OK;
}
if (!strcmp(objstr, "auto")) {
angularUnitConversion = ANGULAR_UNITS_AUTO;
return TCL_OK;
}
if (!strcmp(objstr, "custom")) {
angularUnitConversion = ANGULAR_UNITS_CUSTOM;
return TCL_OK;
}
}
setresult(interp,"emc_angular_unit_conversion: need 'deg', 'rad', 'grad', 'auto', 'custom', or no args");
return TCL_ERROR;
}
static int emc_task_heartbeat(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
Tcl_Obj *hbobj;
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_task_heartbeat: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
hbobj = Tcl_NewIntObj(emcStatus->task.heartbeat);
Tcl_SetObjResult(interp, hbobj);
return TCL_OK;
}
static int emc_task_command(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
Tcl_Obj *commandobj;
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_task_command: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
commandobj = Tcl_NewIntObj(emcStatus->task.command_type);
Tcl_SetObjResult(interp, commandobj);
return TCL_OK;
}
static int emc_task_command_number(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
Tcl_Obj *commandnumber;
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_task_command_number: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
commandnumber = Tcl_NewIntObj(emcStatus->task.echo_serial_number);
Tcl_SetObjResult(interp, commandnumber);
return TCL_OK;
}
static int emc_task_command_status(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
Tcl_Obj *commandstatus;
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_task_command_status: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
commandstatus = Tcl_NewIntObj(emcStatus->task.status);
Tcl_SetObjResult(interp, commandstatus);
return TCL_OK;
}
static int emc_io_heartbeat(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
Tcl_Obj *hbobj;
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_io_heartbeat: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
hbobj = Tcl_NewIntObj(emcStatus->io.heartbeat);
Tcl_SetObjResult(interp, hbobj);
return TCL_OK;
}
static int emc_io_command(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
Tcl_Obj *commandobj;
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_io_command: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
commandobj = Tcl_NewIntObj(emcStatus->io.command_type);
Tcl_SetObjResult(interp, commandobj);
return TCL_OK;
}
static int emc_io_command_number(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
Tcl_Obj *commandnumber;
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_io_command_number: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
commandnumber = Tcl_NewIntObj(emcStatus->io.echo_serial_number);
Tcl_SetObjResult(interp, commandnumber);
return TCL_OK;
}
static int emc_io_command_status(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
Tcl_Obj *commandstatus;
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_io_command_status: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
commandstatus = Tcl_NewIntObj(emcStatus->io.status);
Tcl_SetObjResult(interp, commandstatus);
return TCL_OK;
}
static int emc_motion_heartbeat(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
Tcl_Obj *hbobj;
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_motion_heartbeat: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
hbobj = Tcl_NewIntObj(emcStatus->motion.heartbeat);
Tcl_SetObjResult(interp, hbobj);
return TCL_OK;
}
static int emc_motion_command(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
Tcl_Obj *commandobj;
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_motion_command: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
commandobj = Tcl_NewIntObj(emcStatus->motion.command_type);
Tcl_SetObjResult(interp, commandobj);
return TCL_OK;
}
static int emc_motion_command_number(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
Tcl_Obj *commandnumber;
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_motion_command_number: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
commandnumber = Tcl_NewIntObj(emcStatus->motion.echo_serial_number);
Tcl_SetObjResult(interp, commandnumber);
return TCL_OK;
}
static int emc_motion_command_status(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
Tcl_Obj *commandstatus;
CHECKEMC
if (objc != 1) {
setresult(interp,"emc_motion_command_status: need no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
commandstatus = Tcl_NewIntObj(emcStatus->motion.status);
Tcl_SetObjResult(interp, commandstatus);
return TCL_OK;
}
static int emc_joint_backlash(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
Tcl_Obj *valobj;
int joint;
double backlash;
CHECKEMC
if ((objc < 2) || (objc > 3)) {
setresult(interp,"emc_joint_backlash: need <joint> {<backlash>}");
return TCL_ERROR;
}
if (0 != Tcl_GetIntFromObj(0, objv[1], &joint) ||
joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
setresult(interp,"emc_joint_backlash: need joint as integer, 0..EMCMOT_MAX_JOINTS-1");
return TCL_ERROR;
}
if (objc == 2) {
valobj = Tcl_NewDoubleObj(emcStatus->motion.joint[joint].backlash);
Tcl_SetObjResult(interp, valobj);
return TCL_OK;
} else {
if (0 != Tcl_GetDoubleFromObj(0, objv[2], &backlash)) {
setresult(interp,"emc_joint_backlash: need backlash as real number");
return TCL_ERROR;
}
sendJointSetBacklash(joint, backlash);
return TCL_OK;
}
}
static int emc_joint_enable(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
int joint;
int val;
Tcl_Obj *enobj;
CHECKEMC
if (objc < 2) {
setresult(interp,"emc_joint_enable: need <joint>");
return TCL_ERROR;
}
if (0 != Tcl_GetIntFromObj(0, objv[1], &joint) ||
joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
setresult(interp,"emc_joint_enable: need joint as integer, 0..EMCMOT_MAX_JOINTS-1");
return TCL_ERROR;
}
if (objc == 2) {
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
enobj = Tcl_NewIntObj(emcStatus->motion.joint[joint].enabled);
Tcl_SetObjResult(interp, enobj);
return TCL_OK;
}
if (0 != Tcl_GetIntFromObj(0, objv[2], &val)) {
setresult(interp,"emc_joint_enable: need 0, 1 for disable, enable");
return TCL_ERROR;
}
sendJointEnable(joint, val);
return TCL_OK;
}
static int emc_joint_load_comp(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
int joint, type;
char file[256];
CHECKEMC
if (objc != 4) {
setresult(interp,"emc_joint_load_comp: need <joint> <file> <type>");
return TCL_ERROR;
}
if (0 != Tcl_GetIntFromObj(0, objv[1], &joint) ||
joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
setresult(interp,"emc_joint_load_comp: need joint as integer, 0..EMCMOT_MAX_JOINTS-1");
return TCL_ERROR;
}
strcpy(file, Tcl_GetStringFromObj(objv[2], 0));
if (0 != Tcl_GetIntFromObj(0, objv[3], &type)) {
setresult(interp,"emc_joint_load_comp: <type> must be an int");
}
sendJointLoadComp(joint, file, type);
return TCL_OK;
}
int emc_teleop_enable(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
int enable;
if (objc != 1) {
if (0 != Tcl_GetIntFromObj(0, objv[1], &enable)) {
setresult(interp,"emc_teleop_enable: <enable> must be an integer");
return TCL_ERROR;
}
sendSetTeleopEnable(enable);
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
Tcl_SetObjResult(interp,
Tcl_NewIntObj(emcStatus->motion.traj.mode ==
EMC_TRAJ_MODE_TELEOP));
return TCL_OK;
}
int emc_kinematics_type(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
Tcl_SetObjResult(interp,
Tcl_NewIntObj(emcStatus->motion.traj.
kinematics_type));
return TCL_OK;
}
int emc_probe_clear(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
if (objc != 1) {
setresult(interp,"emc_probe_clear: needs no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
Tcl_SetObjResult(interp, Tcl_NewIntObj(sendClearProbeTrippedFlag()));
return TCL_OK;
}
int emc_probe_value(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
if (objc != 1) {
setresult(interp,"emc_probe_value: needs no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
Tcl_SetObjResult(interp,
Tcl_NewIntObj(emcStatus->motion.traj.probeval));
return TCL_OK;
}
int emc_probe_tripped(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
if (objc != 1) {
setresult(interp,"emc_probe_tripped: needs no args");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
Tcl_SetObjResult(interp,
Tcl_NewIntObj(emcStatus->motion.traj.probe_tripped));
return TCL_OK;
}
int emc_probe_move(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
double x, y, z;
if (objc != 4) {
setresult(interp,"emc_probe_move: <x> <y> <z>");
return TCL_ERROR;
}
if (0 != Tcl_GetDoubleFromObj(0, objv[1], &x)) {
setresult(interp,"emc_probe_move: <x> must be a double");
}
if (0 != Tcl_GetDoubleFromObj(0, objv[2], &y)) {
setresult(interp,"emc_probe_move: <y> must be a double");
}
if (0 != Tcl_GetDoubleFromObj(0, objv[3], &z)) {
setresult(interp,"emc_probe_move: <z> must be a double");
}
Tcl_SetObjResult(interp, Tcl_NewIntObj(sendProbe(x, y, z)));
return TCL_OK;
}
static int emc_probed_pos(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
char string[1];
Tcl_Obj *posobj;
CHECKEMC
if (objc != 2) {
setresult(interp,"emc_probed_pos: need exactly 1 non-negative integer");
return TCL_ERROR;
}
if (emcUpdateType == EMC_UPDATE_AUTO) {
updateStatus();
}
strncpy(string, Tcl_GetStringFromObj(objv[1], 0),1);
switch (string[0]) {
case 'x': case 'X':
posobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->motion.traj.probedPosition.tran.x));
break;
case 'y': case 'Y':
posobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->motion.traj.probedPosition.tran.y));
break;
case 'z': case 'Z':
posobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->motion.traj.probedPosition.tran.z));
break;
case 'a': case 'A':
posobj = Tcl_NewDoubleObj(convertAngularUnits(
emcStatus->motion.traj.probedPosition.a));
break;
case 'b': case 'B':
posobj = Tcl_NewDoubleObj(convertAngularUnits(
emcStatus->motion.traj.probedPosition.b));
break;
case 'c': case 'C':
posobj = Tcl_NewDoubleObj(convertAngularUnits(
emcStatus->motion.traj.probedPosition.c));
break;
case 'u': case 'U':
posobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->motion.traj.probedPosition.u));
break;
case 'v': case 'V':
posobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->motion.traj.probedPosition.v));
break;
case 'w': case 'W':
posobj = Tcl_NewDoubleObj(convertLinearUnits(
emcStatus->motion.traj.probedPosition.w));
break;
default:
setresult(interp,"emc_probed_pos: bad coordinate letter argument");
return TCL_ERROR;
}
Tcl_SetObjResult(interp, posobj);
return TCL_OK;
}
static int emc_pendant(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
FILE *inFile;
char inBytes[5];
const char *port;
inBytes[0] = 0;
inBytes[1] = 0;
inBytes[2] = 0;
inBytes[3] = 0;
inBytes[4] = 0;
CHECKEMC
if (objc == 2) {
port = Tcl_GetStringFromObj(objv[1], 0);
if ((!strcmp(port, "/dev/psaux")) | (!strcmp(port,
"/dev/ttyS0")) |
(!strcmp(port, "/dev/ttyS1"))) {
inFile = fopen(port, "r+b");
if (inFile) {
if (strcmp(port, "/dev/psaux")) { inBytes[1] = fgetc(inFile); if (inBytes[1] != 77) { fputc(77, inFile); fflush(inFile);
inBytes[1] = fgetc(inFile); }
}
inBytes[4] = fgetc(inFile); inBytes[2] = fgetc(inFile); inBytes[3] = fgetc(inFile); }
fclose(inFile);
if (!strcmp(port, "/dev/psaux")) { inBytes[0] = (inBytes[4] & 0x01); inBytes[1] = (inBytes[4] & 0x02) >> 1; } else { inBytes[0] = (inBytes[4] & 0x20) >> 5; inBytes[1] = (inBytes[4] & 0x10) >> 4; if (inBytes[4] & 0x02) {
inBytes[2] = inBytes[2] | 0xc0;
}
if (inBytes[4] & 0x08) {
inBytes[3] = inBytes[3] | 0xc0;
}
}
char buf[80];
snprintf(buf, sizeof(buf), "%i %i %d %d %i", inBytes[0],
inBytes[1], inBytes[2], inBytes[3], inBytes[4]);
Tcl_SetResult(interp, buf, TCL_VOLATILE);
return TCL_OK;
}
}
setresult(interp,"Need /dev/psaux, /dev/ttyS0 or /dev/ttyS1 as Arg");
return TCL_ERROR;
}
static int localint(ClientData clientdata,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
double val;
char resstring[80];
if (objc != 2) {
setresult(interp, "wrong # args: should be \"int value\"");
return TCL_ERROR;
}
if (0 != Tcl_GetDoubleFromObj(0, objv[1], &val)) {
resstring[0] = 0;
strcat(resstring, "expected number but got \"");
strncat(resstring, Tcl_GetStringFromObj(objv[1], 0),
sizeof(resstring) - strlen(resstring) - 2);
strcat(resstring, "\"");
setresult(interp, resstring);
return TCL_ERROR;
}
Tcl_SetObjResult(interp, Tcl_NewIntObj((int) val));
return TCL_OK;
}
static const char *one_head(int x0, int y0, int x1, int y1)
{
static char buf[100];
snprintf(buf, sizeof(buf), "%d %d %d %d", x0, y0, x1, y1);
return buf;
}
static int localround(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
double val;
char resstring[80];
if (objc != 2) {
setresult(interp,"wrong # args: should be \"round value\"");
return TCL_ERROR;
}
if (0 != Tcl_GetDoubleFromObj(0, objv[1], &val)) {
resstring[0] = 0;
strcat(resstring, "expected number but got \"");
strncat(resstring, Tcl_GetStringFromObj(objv[1], 0),
sizeof(resstring) - strlen(resstring) - 2);
strcat(resstring, "\"");
setresult(interp,resstring);
return TCL_ERROR;
}
Tcl_SetObjResult(interp,
Tcl_NewIntObj(val <
0.0 ? (int) (val - 0.5) : (int) (val +
0.5)));
return TCL_OK;
}
#include <X11/extensions/Xinerama.h>
static int multihead(ClientData clientdata,
Tcl_Interp * interp, int objc,
Tcl_Obj * CONST objv[])
{
if(objc > 1)
setresult(interp,"wrong # args: should be \"multihead\"");
Tk_Window tkwin = Tk_MainWindow(interp);
if(!tkwin) return TCL_ERROR;
Display *d = Tk_Display(tkwin);
if(!d) return TCL_ERROR;
Tcl_ResetResult(interp);
XineramaScreenInfo *inf = NULL;
int count = 0;
int i, j;
if(XineramaQueryExtension(d, &i, &j)) {
inf = XineramaQueryScreens(d, &count);
}
if( !inf ) {
Tcl_AppendElement(interp, one_head(0, 0,
DisplayWidth(d, DefaultScreen(d)),
DisplayHeight(d, DefaultScreen(d))));
} else {
for(i=0; i<count; i++) {
Tcl_AppendElement(interp, one_head(inf[i].x_org, inf[i].y_org,
inf[i].x_org + inf[i].width,
inf[i].y_org + inf[i].height));
}
XFree(inf);
}
return TCL_OK;
}
static void sigQuit(int sig)
{
thisQuit((ClientData) 0);
}
static void initMain()
{
emcWaitType = EMC_WAIT_RECEIVED;
emcCommandSerialNumber = 0;
emcTimeout = 0.0;
emcUpdateType = EMC_UPDATE_AUTO;
linearUnitConversion = LINEAR_UNITS_AUTO;
angularUnitConversion = ANGULAR_UNITS_AUTO;
emcCommandBuffer = 0;
emcStatusBuffer = 0;
emcStatus = 0;
emcErrorBuffer = 0;
error_string[LINELEN-1] = 0;
operator_text_string[LINELEN-1] = 0;
operator_display_string[LINELEN-1] = 0;
programStartLine = 0;
}
int emc_init(ClientData cd, Tcl_Interp *interp, int argc, const char **argv)
{
bool quick = false;
initMain();
if (0 != emcGetArgs(argc, (char**)argv)) {
setresult(interp,"error in argument list\n");
return TCL_ERROR;
}
iniLoad(emc_inifile);
for(int i=1; i<argc; i++)
{
if(!strcmp(argv[i], "-quick")) quick = true;
}
Tcl_SetVar(interp, "EMC_INIFILE", emc_inifile, TCL_GLOBAL_ONLY);
if (0 != tryNml(quick ? 0.0 : 10.0, quick ? 0.0 : 1.0)) {
setresult(interp,"no emc connection");
thisQuit(NULL);
return TCL_ERROR;
}
updateStatus();
emcCommandSerialNumber = emcStatus->echo_serial_number;
Tcl_CreateExitHandler(thisQuit, (ClientData) 0);
signal(SIGINT, sigQuit);
setresult(interp,"");
return TCL_OK;
}
extern "C"
int Linuxcnc_Init(Tcl_Interp * interp);
int Linuxcnc_Init(Tcl_Interp * interp)
{
if (Tcl_InitStubs(interp, "8.1", 0) == NULL)
{
return TCL_ERROR;
}
Tcl_CreateCommand(interp, "emc_init", emc_init, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_plat", emc_plat, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_ini", emc_ini, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_debug", emc_Debug, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_set_wait", emc_set_wait,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_wait", emc_wait, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_set_timeout", emc_set_timeout,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_update", emc_update,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_time", emc_time, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_error", emc_error, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_operator_text", emc_operator_text,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_operator_display",
emc_operator_display, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_estop", emc_estop, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_machine", emc_machine,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_mode", emc_mode, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_mist", emc_mist, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_flood", emc_flood, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_lube", emc_lube, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_lube_level", emc_lube_level,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_spindle", emc_spindle,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_brake", emc_brake, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_tool", emc_tool, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_tool_offset", emc_tool_offset,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_load_tool_table",
emc_load_tool_table, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_set_tool_offset",
emc_set_tool_offset, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_abs_cmd_pos", emc_abs_cmd_pos,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_abs_act_pos", emc_abs_act_pos,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_rel_cmd_pos", emc_rel_cmd_pos,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_rel_act_pos", emc_rel_act_pos,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_joint_pos", emc_joint_pos,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_pos_offset", emc_pos_offset,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_joint_limit", emc_joint_limit,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_joint_fault", emc_joint_fault,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_override_limit", emc_override_limit,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_optional_stop", emc_optional_stop,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_joint_homed", emc_joint_homed,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_mdi", emc_mdi, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_home", emc_home, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_unhome", emc_unhome, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_jog_stop", emc_jog_stop,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_jog", emc_jog, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_jog_incr", emc_jog_incr,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_feed_override", emc_feed_override,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_rapid_override", emc_rapid_override,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_spindle_override", emc_spindle_override,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_task_plan_init", emc_task_plan_init,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_open", emc_open, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_run", emc_run, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_pause", emc_pause, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_resume", emc_resume,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_step", emc_step, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_abort", emc_abort, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_program", emc_program,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_program_line", emc_program_line,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_program_status", emc_program_status,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_program_codes", emc_program_codes,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_joint_type", emc_joint_type,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_joint_units", emc_joint_units,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_program_linear_units",
emc_program_linear_units, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_program_angular_units",
emc_program_angular_units, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_user_linear_units",
emc_user_linear_units, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_user_angular_units",
emc_user_angular_units, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_display_linear_units",
emc_display_linear_units, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_display_angular_units",
emc_display_angular_units, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_linear_unit_conversion",
emc_linear_unit_conversion, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_angular_unit_conversion",
emc_angular_unit_conversion, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_task_heartbeat", emc_task_heartbeat,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_task_command", emc_task_command,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_task_command_number",
emc_task_command_number, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_task_command_status",
emc_task_command_status, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_io_heartbeat", emc_io_heartbeat,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_io_command", emc_io_command,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_io_command_number",
emc_io_command_number, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_io_command_status",
emc_io_command_status, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_motion_heartbeat",
emc_motion_heartbeat, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_motion_command", emc_motion_command,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_motion_command_number",
emc_motion_command_number, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_motion_command_status",
emc_motion_command_status, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_joint_backlash", emc_joint_backlash,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_joint_load_comp", emc_joint_load_comp,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_joint_enable", emc_joint_enable,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_teleop_enable", emc_teleop_enable,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_kinematics_type",
emc_kinematics_type, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_probe_clear", emc_probe_clear,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_probe_value", emc_probe_value,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_probe_tripped", emc_probe_tripped,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_probe_move", emc_probe_move,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_probed_pos", emc_probed_pos,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "emc_pendant", emc_pendant,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "int", localint, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "round", localround, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "multihead", multihead, (ClientData) NULL,
(Tcl_CmdDeleteProc*) NULL);
Tcl_SetVar(interp, "tcl_rcFileName", "~/.emcshrc", TCL_GLOBAL_ONLY);
Tcl_SetVar(interp, "EMC_INIFILE", emc_inifile, TCL_GLOBAL_ONLY);
Tcl_PkgProvide(interp, "Linuxcnc", "1.0");
Tcl_ResetResult(interp);
return TCL_OK;
}