#include "config.h"
#include <stdlib.h>
#include <sys/stat.h>
#include <string.h>
#include <float.h>
#include "motion.h"
#include "motion_debug.h"
#include "motion_struct.h"
#include "emcmotcfg.h"
#include "emcmotglb.h"
#include "usrmotintf.h"
#include "_timer.h"
#include "rcs_print.hh"
#include "inifile.hh"
#define READ_TIMEOUT_SEC 0
#define READ_TIMEOUT_USEC 100000
#include "rtapi.h"
#include "dbuf.h"
#include "stashf.h"
static int inited = 0;
static emcmot_command_t *emcmotCommand = 0;
static emcmot_status_t *emcmotStatus = 0;
static emcmot_config_t *emcmotConfig = 0;
static emcmot_debug_t *emcmotDebug = 0;
static emcmot_error_t *emcmotError = 0;
static emcmot_struct_t *emcmotStruct = 0;
int usrmotIniLoad(const char *filename)
{
IniFile inifile(IniFile::ERR_CONVERSION);
if (!inifile.Open(filename)) {
rtapi_print("can't find emcmot ini file %s\n", filename);
return -1;
}
try {
inifile.Find((int *)&SHMEM_KEY, "SHMEM_KEY", "EMCMOT");
inifile.Find(&EMCMOT_COMM_TIMEOUT, "COMM_TIMEOUT", "EMCMOT");
}
catch(IniFile::Exception &e){
e.Print();
return -1;
}
return 0;
}
int usrmotWriteEmcmotCommand(emcmot_command_t * c)
{
emcmot_status_t s;
static int commandNum = 0;
static unsigned char headCount = 0;
double end;
if (!MOTION_ID_VALID(c->id)) {
rcs_print("USRMOT: ERROR: invalid motion id: %d\n",c->id);
return EMCMOT_COMM_INVALID_MOTION_ID;
}
c->head = ++headCount;
c->tail = c->head;
c->commandNum = ++commandNum;
if (0 == emcmotCommand) {
rcs_print("USRMOT: ERROR: can't connect to shared memory\n");
return EMCMOT_COMM_ERROR_CONNECT;
}
*emcmotCommand = *c;
end = etime() + EMCMOT_COMM_TIMEOUT;
while (etime() < end) {
if (( usrmotReadEmcmotStatus(&s) == 0 ) && ( s.commandNumEcho == commandNum )) {
if (s.commandStatus == EMCMOT_COMMAND_OK) {
return EMCMOT_COMM_OK;
} else {
rcs_print("USRMOT: ERROR: invalid command\n");
return EMCMOT_COMM_ERROR_COMMAND;
}
}
esleep(25e-6);
}
rcs_print("USRMOT: ERROR: command timeout\n");
return EMCMOT_COMM_ERROR_TIMEOUT;
}
int usrmotReadEmcmotStatus(emcmot_status_t * s)
{
int split_read_count;
if (0 == emcmotStatus) {
return EMCMOT_COMM_ERROR_CONNECT;
}
split_read_count = 0;
do {
memcpy(s, emcmotStatus, sizeof(emcmot_status_t));
if (s->head == s->tail) {
return EMCMOT_COMM_OK;
}
} while ( ++split_read_count < 3 );
return EMCMOT_COMM_SPLIT_READ_TIMEOUT;
}
int usrmotReadEmcmotConfig(emcmot_config_t * s)
{
int split_read_count;
if (0 == emcmotConfig) {
return EMCMOT_COMM_ERROR_CONNECT;
}
split_read_count = 0;
do {
memcpy(s, emcmotConfig, sizeof(emcmot_config_t));
if (s->head == s->tail) {
return EMCMOT_COMM_OK;
}
} while ( ++split_read_count < 3 );
printf("ReadEmcmotConfig COMM_SPLIT_READ_TIMEOUT\n" );
return EMCMOT_COMM_SPLIT_READ_TIMEOUT;
}
int usrmotReadEmcmotDebug(emcmot_debug_t * s)
{
int split_read_count;
if (0 == emcmotDebug) {
return EMCMOT_COMM_ERROR_CONNECT;
}
split_read_count = 0;
do {
memcpy(s, emcmotDebug, sizeof(emcmot_debug_t));
if (s->head == s->tail) {
return EMCMOT_COMM_OK;
}
} while ( ++split_read_count < 3 );
printf("ReadEmcmotDebug COMM_SPLIT_READ_TIMEOUT\n" );
return EMCMOT_COMM_SPLIT_READ_TIMEOUT;
}
int usrmotReadEmcmotError(char *e)
{
if (emcmotError == 0) {
return -1;
}
char data[EMCMOT_ERROR_LEN];
struct dbuf d;
dbuf_init(&d, (unsigned char *)data, EMCMOT_ERROR_LEN);
int result = emcmotErrorGet(emcmotError, data);
if(result < 0) return result;
struct dbuf_iter di;
dbuf_iter_init(&di, &d);
result = snprintdbuf(e, EMCMOT_ERROR_LEN, &di);
if(result < 0) return result;
return 0;
}
#if 0#endif
void printEmcPose(EmcPose * pose)
{
printf("x=%f\ty=%f\tz=%f\tu=%f\tv=%f\tw=%f\ta=%f\tb=%f\tc=%f",
pose->tran.x, pose->tran.y, pose->tran.z,
pose->u, pose->v, pose->w,
pose->a, pose->b, pose->c);
}
void printTPstruct(TP_STRUCT * tp)
{
printf("queueSize=%d\n", tp->queueSize);
printf("cycleTime=%f\n", tp->cycleTime);
printf("vMax=%f\n", tp->vMax);
printf("aMax=%f\n", tp->aMax);
printf("vLimit=%f\n", tp->vLimit);
printf("wMax=%f\n", tp->wMax);
printf("wDotMax=%f\n", tp->wDotMax);
printf("nextId=%d\n", tp->nextId);
printf("execId=%d\n", tp->execId);
printf("termCond=%d\n", tp->termCond);
printf("currentPos :");
printEmcPose(&tp->currentPos);
printf("\n");
printf("goalPos :");
printEmcPose(&tp->goalPos);
printf("\n");
printf("done=%d\n", tp->done);
printf("depth=%d\n", tp->depth);
printf("activeDepth=%d\n", tp->activeDepth);
printf("aborting=%d\n", tp->aborting);
printf("pausing=%d\n", tp->pausing);
}
void usrmotPrintEmcmotDebug(emcmot_debug_t *d, int which)
{
printf("running time: \t%f\n", d->running_time);
switch (which) {
#if 0#endif
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
#if 0#endif
break;
case 12:
#if 0#endif
printf("\n");
default:
break;
}
}
void usrmotPrintEmcmotConfig(emcmot_config_t c, int which)
{
switch (which) {
case 0:
printf("debug level \t%d\n", c.debug);
printf("traj time: \t%f\n", c.trajCycleTime);
printf("servo time: \t%f\n", c.servoCycleTime);
printf("interp rate: \t%d\n", c.interpolationRate);
printf("v limit: \t%f\n", c.limitVel);
printf("axis vlimit: \t");
#if 0#endif
printf("\n");
break;
case 1:
printf("pid stuff is obsolete\n");
#if 0#endif
break;
case 3:
#if 0#endif
break;
default:
break;
}
}
void usrmotPrintEmcmotStatus(emcmot_status_t *s, int which)
{
switch (which) {
case 0:
printf("mode: \t%s\n",
s->motionFlag & EMCMOT_MOTION_TELEOP_BIT ? "teleop" :
(s->motionFlag & EMCMOT_MOTION_COORD_BIT ? "coord" : "free")
);
printf("cmd: \t%d\n", s->commandEcho);
printf("cmd num: \t%d\n", s->commandNumEcho);
printf("heartbeat: \t%u\n", s->heartbeat);
#if 0#endif
printf("cmd pos: \t%f\t%f\t%f\t%f\t%f\t%f\n",
s->carte_pos_cmd.tran.x, s->carte_pos_cmd.tran.y,
s->carte_pos_cmd.tran.z, s->carte_pos_cmd.a, s->carte_pos_cmd.b,
s->carte_pos_cmd.c);
printf("act pos: \t%f\t%f\t%f\t%f\t%f\t%f\n",
s->carte_pos_fb.tran.x, s->carte_pos_fb.tran.y,
s->carte_pos_fb.tran.z, s->carte_pos_fb.a, s->carte_pos_fb.b,
s->carte_pos_fb.c);
printf("joint data:\n");
#if 0#endif
printf("velocity: \t%f\n", s->vel);
printf("accel: \t%f\n", s->acc);
printf("id: \t%d\n", s->id);
printf("depth: \t%d\n", s->depth);
printf("active depth: \t%d\n", s->activeDepth);
printf("inpos: \t%d\n",
s->motionFlag & EMCMOT_MOTION_INPOS_BIT ? 1 : 0);
#if 0#endif
printf("enabled: \t%s\n",
s->motionFlag & EMCMOT_MOTION_ENABLE_BIT ? "ENABLED" : "DISABLED");
printf("probe value: %d\n", s->probeVal);
printf("probe Tripped: %d\n", s->probeTripped);
printf("probing: %d\n", s->probing);
printf("probed pos: \t%f\t%f\t%f\n",
s->probedPos.tran.x, s->probedPos.tran.y, s->probedPos.tran.z);
break;
case 2:
#if 0#endif
printf("fault\n");
printf("\npolarity: ");
printf("limit override mask: %08x\n", s->overrideLimitMask);
break;
case 4:
printf("scales handled in HAL now!\n");
#if 0#endif
break;
default:
break;
}
}
static int module_id;
static int shmem_id;
int usrmotInit(const char *modname)
{
int retval;
module_id = rtapi_init(modname);
if (module_id < 0) {
fprintf(stderr,
"usrmotintf: ERROR: rtapi init failed\n");
return -1;
}
shmem_id = rtapi_shmem_new(SHMEM_KEY, module_id, sizeof(emcmot_struct_t));
if (shmem_id < 0) {
fprintf(stderr,
"usrmotintf: ERROR: could not open shared memory\n");
rtapi_exit(module_id);
return -1;
}
retval = rtapi_shmem_getptr(shmem_id, (void **) &emcmotStruct);
if (retval < 0) {
rtapi_print_msg(RTAPI_MSG_ERR,
"usrmotintf: ERROR: could not access shared memory\n");
rtapi_exit(module_id);
return -1;
}
emcmotCommand = &(emcmotStruct->command);
emcmotStatus = &(emcmotStruct->status);
emcmotDebug = &(emcmotStruct->debug);
emcmotConfig = &(emcmotStruct->config);
emcmotError = &(emcmotStruct->error);
inited = 1;
return 0;
}
int usrmotExit(void)
{
if (NULL != emcmotStruct) {
rtapi_shmem_delete(shmem_id, module_id);
rtapi_exit(module_id);
}
emcmotStruct = 0;
emcmotCommand = 0;
emcmotStatus = 0;
emcmotError = 0;
#if 0#endif
inited = 0;
return 0;
}
int usrmotLoadComp(int joint, const char *file, int type)
{
FILE *fp;
char buffer[LINELEN];
double nom, fwd, rev;
int ret = 0;
emcmot_command_t emcmotCommand;
if (joint < 0 || joint >= EMCMOT_MAX_JOINTS) {
fprintf(stderr, "joint out of range for compensation\n");
return -1;
}
if (NULL == (fp = fopen(file, "r"))) {
fprintf(stderr, "can't open compensation file %s\n", file);
return -1;
}
while (!feof(fp)) {
if (NULL == fgets(buffer, LINELEN, fp)) {
break;
}
if (3 != sscanf(buffer, "%lf %lf %lf", &nom, &fwd, &rev)) {
break;
} else {
if (type == 0) {
emcmotCommand.comp_nominal = nom;
emcmotCommand.comp_forward = nom - fwd; emcmotCommand.comp_reverse = nom - rev; } else {
emcmotCommand.comp_nominal = nom;
emcmotCommand.comp_forward = fwd;
emcmotCommand.comp_reverse = rev;
}
emcmotCommand.joint = joint;
emcmotCommand.command = EMCMOT_SET_JOINT_COMP;
ret |= usrmotWriteEmcmotCommand(&emcmotCommand);
}
}
fclose(fp);
return ret;
}
int usrmotPrintComp(int joint)
{
return -1;
#if 0#endif
}