00001 #ifdef rtlinux
00002 #define MODULE
00003 #endif
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 #ifdef rtlinux
00175
00176
00177
00178
00179
00180 #include <linux/module.h>
00181 #include <linux/kernel.h>
00182 #include <linux/version.h>
00183 #include <linux/errno.h>
00184 #if defined(rtlinux_09J) || defined(rtlinux_1_0)
00185 #include <rtl_sched.h>
00186 #include <rtl_fifo.h>
00187 #else
00188 #include <linux/rt_sched.h>
00189 #include <linux/rtf.h>
00190 #endif
00191 #include <asm/io.h>
00192
00193 #include <math.h>
00194 #include <stdarg.h>
00195
00196 #else
00197
00198 #include "_timer.h"
00199 #include "_shm.h"
00200 #include <stdio.h>
00201 #include <stdlib.h>
00202 #include <math.h>
00203 #include <stdarg.h>
00204 #include <string.h>
00205
00206 #endif
00207
00208 #include "emcpos.h"
00209 #include "emcmotcfg.h"
00210 #include "emcmotglb.h"
00211 #include "emcmot.h"
00212 #include "pid.h"
00213 #include "cubic.h"
00214
00215 #include "tc.h"
00216 #include "tp.h"
00217
00218 #include "segmentqueue.h"
00219
00220 #include "extintf.h"
00221 #include "mmxavg.h"
00222 #include "emcmotlog.h"
00223
00224
00225 static char ident[] = "$Id: emcsegmot.c,v 1.3 2000/12/21 16:22:11 wshackle Exp $";
00226
00227 #ifdef rtlinux
00228
00229
00230
00231 #define SECS_TO_RTIME(secs) ((RTIME) (RT_TICKS_PER_SEC * secs))
00232
00233
00234 static RT_TASK emcmotTask;
00235 #define RT_TASK_PRIORITY 1
00236
00237 #define RT_TASK_STACK_SIZE 2048
00238
00239
00240
00241 static RT_TASK smTask;
00242 #define SM_TASK_PRIORITY 2
00243 #define SM_TASK_STACK_SIZE 2048
00244
00245
00246
00247 #define SOUND_PORT 0x61
00248 #define SOUND_MASK 0xFD;
00249 static unsigned char soundByte;
00250 static unsigned char toggle = 0;
00251
00252 #endif
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 #if defined (rtlinux) && defined (RT_FIFO)
00278
00279
00280 static EMCMOT_COMMAND emcmotCommandBuffer;
00281 static EMCMOT_STATUS emcmotStatusBuffer;
00282
00283 #else
00284
00285
00286 EMCMOT_STRUCT *emcmotStruct;
00287
00288 #ifndef rtlinux
00289
00290 static shm_t *shmem = NULL;
00291 #endif
00292
00293 #endif
00294
00295
00296
00297 static EMCMOT_COMMAND *emcmotCommand;
00298 static EMCMOT_STATUS *emcmotStatus;
00299 #if defined (rtlinux) && defined (RT_FIFO)
00300 #else
00301 static EMCMOT_ERROR *emcmotError;
00302 static EMCMOT_LOG *emcmotLog;
00303 #endif
00304
00305 static EMCMOT_LOG_STRUCT ls;
00306 static int logSkip = 0;
00307 static int loggingAxis = 0;
00308 static int logIt = 0;
00309
00310
00311 static int wdEnable = 0;
00312 static int wdWait = 0;
00313 static int wdCount = 0;
00314
00315
00316 #define LIMIT_SWITCH_DEBOUNCE 10
00317 static int maxLimitSwitchCount[EMCMOT_MAX_AXIS];
00318 static int minLimitSwitchCount[EMCMOT_MAX_AXIS];
00319
00320
00321 #ifdef rtlinux
00322 #define diagnostics printk
00323 #else
00324 #define diagnostics printf
00325 #endif
00326
00327
00328
00329
00330
00331 #define GET_MOTION_ERROR_FLAG() (emcmotStatus->motionFlag & EMCMOT_MOTION_ERROR_BIT ? 1 : 0)
00332
00333 #define SET_MOTION_ERROR_FLAG(fl) if (fl) emcmotStatus->motionFlag |= EMCMOT_MOTION_ERROR_BIT; else emcmotStatus->motionFlag &= ~EMCMOT_MOTION_ERROR_BIT;
00334
00335 #define GET_MOTION_COORD_FLAG() (emcmotStatus->motionFlag & EMCMOT_MOTION_COORD_BIT ? 1 : 0)
00336
00337 #define SET_MOTION_COORD_FLAG(fl) if (fl) emcmotStatus->motionFlag |= EMCMOT_MOTION_COORD_BIT; else emcmotStatus->motionFlag &= ~EMCMOT_MOTION_COORD_BIT;
00338
00339 #define GET_MOTION_INPOS_FLAG() (emcmotStatus->motionFlag & EMCMOT_MOTION_INPOS_BIT ? 1 : 0)
00340
00341 #define SET_MOTION_INPOS_FLAG(fl) if (fl) emcmotStatus->motionFlag |= EMCMOT_MOTION_INPOS_BIT; else emcmotStatus->motionFlag &= ~EMCMOT_MOTION_INPOS_BIT;
00342
00343 #define GET_MOTION_ENABLE_FLAG() (emcmotStatus->motionFlag & EMCMOT_MOTION_ENABLE_BIT ? 1 : 0)
00344
00345 #define SET_MOTION_ENABLE_FLAG(fl) if (fl) emcmotStatus->motionFlag |= EMCMOT_MOTION_ENABLE_BIT; else emcmotStatus->motionFlag &= ~EMCMOT_MOTION_ENABLE_BIT;
00346
00347
00348
00349 #define GET_AXIS_ENABLE_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_ENABLE_BIT ? 1 : 0)
00350
00351 #define SET_AXIS_ENABLE_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_ENABLE_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_ENABLE_BIT;
00352
00353 #define GET_AXIS_ACTIVE_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_ACTIVE_BIT ? 1 : 0)
00354
00355 #define SET_AXIS_ACTIVE_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_ACTIVE_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_ACTIVE_BIT;
00356
00357 #define GET_AXIS_INPOS_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_INPOS_BIT ? 1 : 0)
00358
00359 #define SET_AXIS_INPOS_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_INPOS_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_INPOS_BIT;
00360
00361 #define GET_AXIS_ERROR_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_ERROR_BIT ? 1 : 0)
00362
00363 #define SET_AXIS_ERROR_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_ERROR_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_ERROR_BIT;
00364
00365 #define GET_AXIS_PSL_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_MAX_SOFT_LIMIT_BIT ? 1 : 0)
00366
00367 #define SET_AXIS_PSL_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_MAX_SOFT_LIMIT_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_MAX_SOFT_LIMIT_BIT;
00368
00369 #define GET_AXIS_NSL_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_MIN_SOFT_LIMIT_BIT ? 1 : 0)
00370
00371 #define SET_AXIS_NSL_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_MIN_SOFT_LIMIT_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_MIN_SOFT_LIMIT_BIT;
00372
00373 #define GET_AXIS_PHL_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_MAX_HARD_LIMIT_BIT ? 1 : 0)
00374
00375 #define SET_AXIS_PHL_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_MAX_HARD_LIMIT_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_MAX_HARD_LIMIT_BIT;
00376
00377 #define GET_AXIS_NHL_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_MIN_HARD_LIMIT_BIT ? 1 : 0)
00378
00379 #define SET_AXIS_NHL_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_MIN_HARD_LIMIT_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_MIN_HARD_LIMIT_BIT;
00380
00381 #define GET_AXIS_HOME_SWITCH_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_HOME_SWITCH_BIT ? 1 : 0)
00382
00383 #define SET_AXIS_HOME_SWITCH_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_HOME_SWITCH_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_HOME_SWITCH_BIT;
00384
00385 #define GET_AXIS_HOMING_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_HOMING_BIT ? 1 : 0)
00386
00387 #define SET_AXIS_HOMING_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_HOMING_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_HOMING_BIT;
00388
00389 #define GET_AXIS_HOMED_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_HOMED_BIT ? 1 : 0)
00390
00391 #define SET_AXIS_HOMED_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_HOMED_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_HOMED_BIT;
00392
00393 #define GET_AXIS_FERROR_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_FERROR_BIT ? 1 : 0)
00394
00395 #define SET_AXIS_FERROR_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_FERROR_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_FERROR_BIT;
00396
00397 #define GET_AXIS_FAULT_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_FAULT_BIT ? 1 : 0)
00398
00399 #define SET_AXIS_FAULT_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_FAULT_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_FAULT_BIT;
00400
00401
00402
00403 #define GET_AXIS_ENABLE_POLARITY(ax) (emcmotStatus->axisPolarity[ax] & EMCMOT_AXIS_ENABLE_BIT ? 1 : 0)
00404
00405 #define SET_AXIS_ENABLE_POLARITY(ax,fl) if (fl) emcmotStatus->axisPolarity[ax] |= EMCMOT_AXIS_ENABLE_BIT; else emcmotStatus->axisPolarity[ax] &= ~EMCMOT_AXIS_ENABLE_BIT;
00406
00407 #define GET_AXIS_PHL_POLARITY(ax) (emcmotStatus->axisPolarity[ax] & EMCMOT_AXIS_MAX_HARD_LIMIT_BIT ? 1 : 0)
00408
00409 #define SET_AXIS_PHL_POLARITY(ax,fl) if (fl) emcmotStatus->axisPolarity[ax] |= EMCMOT_AXIS_MAX_HARD_LIMIT_BIT; else emcmotStatus->axisPolarity[ax] &= ~EMCMOT_AXIS_MAX_HARD_LIMIT_BIT;
00410
00411 #define GET_AXIS_NHL_POLARITY(ax) (emcmotStatus->axisPolarity[ax] & EMCMOT_AXIS_MIN_HARD_LIMIT_BIT ? 1 : 0)
00412
00413 #define SET_AXIS_NHL_POLARITY(ax,fl) if (fl) emcmotStatus->axisPolarity[ax] |= EMCMOT_AXIS_MIN_HARD_LIMIT_BIT; else emcmotStatus->axisPolarity[ax] &= ~EMCMOT_AXIS_MIN_HARD_LIMIT_BIT;
00414
00415 #define GET_AXIS_HOME_SWITCH_POLARITY(ax) (emcmotStatus->axisPolarity[ax] & EMCMOT_AXIS_HOME_SWITCH_BIT ? 1 : 0)
00416
00417 #define SET_AXIS_HOME_SWITCH_POLARITY(ax,fl) if (fl) emcmotStatus->axisPolarity[ax] |= EMCMOT_AXIS_HOME_SWITCH_BIT; else emcmotStatus->axisPolarity[ax] &= ~EMCMOT_AXIS_HOME_SWITCH_BIT;
00418
00419 #define GET_AXIS_HOMING_POLARITY(ax) (emcmotStatus->axisPolarity[ax] & EMCMOT_AXIS_HOMING_BIT ? 1 : 0)
00420
00421 #define SET_AXIS_HOMING_POLARITY(ax,fl) if (fl) emcmotStatus->axisPolarity[ax] |= EMCMOT_AXIS_HOMING_BIT; else emcmotStatus->axisPolarity[ax] &= ~EMCMOT_AXIS_HOMING_BIT;
00422
00423 #define GET_AXIS_FAULT_POLARITY(ax) (emcmotStatus->axisPolarity[ax] & EMCMOT_AXIS_FAULT_BIT ? 1 : 0)
00424
00425 #define SET_AXIS_FAULT_POLARITY(ax,fl) if (fl) emcmotStatus->axisPolarity[ax] |= EMCMOT_AXIS_FAULT_BIT; else emcmotStatus->axisPolarity[ax] &= ~EMCMOT_AXIS_FAULT_BIT;
00426
00427 static SEGMENTQUEUE queue;
00428 static SEGMENT *sqMemPool;
00429
00430
00431 static TP_STRUCT freeAxis[EMCMOT_MAX_AXIS];
00432 static CUBIC_STRUCT cubic[EMCMOT_MAX_AXIS];
00433
00434
00435
00436 static TC_STRUCT queueTcSpace[DEFAULT_TC_QUEUE_SIZE + 10];
00437 #define FREE_AXIS_QUEUE_SIZE 4
00438 static TC_STRUCT freeAxisTcSpace[EMCMOT_MAX_AXIS][FREE_AXIS_QUEUE_SIZE];
00439
00440 static double rawInput[EMCMOT_MAX_AXIS];
00441 static double rawOutput[EMCMOT_MAX_AXIS];
00442
00443 static double trajPos[EMCMOT_MAX_AXIS];
00444 static double jointPos[EMCMOT_MAX_AXIS];
00445 static double oldJointPos[EMCMOT_MAX_AXIS];
00446 static double oldInput[EMCMOT_MAX_AXIS];
00447 static EmcPose oldPos;
00448 static EmcPose oldVel, newVel;
00449 static EmcPose newAcc;
00450
00451
00452 static double lastInput[EMCMOT_MAX_AXIS];
00453
00454
00455 static double bigVel = 1.0;
00456
00457 static int waitingForLatch[EMCMOT_MAX_AXIS];
00458 static int latchFlag[EMCMOT_MAX_AXIS];
00459 static double saveLatch[EMCMOT_MAX_AXIS];
00460
00461 static int enabling = 0;
00462 static int coordinating = 0;
00463
00464 static int wasOnLimit[EMCMOT_MAX_AXIS];
00465
00466 static int stepping = 0;
00467 static int idForStep = 0;
00468
00469
00470
00471
00472 #include "parport.h"
00473
00474 static double smStepsPerUnit[EMCMOT_MAX_AXIS];
00475 static int smStepsAccum[EMCMOT_MAX_AXIS];
00476 static unsigned char smClkPhase[EMCMOT_MAX_AXIS];
00477
00478
00479
00480
00481 static MMXAVG_STRUCT tMmxavg;
00482 static MMXAVG_STRUCT sMmxavg;
00483 static MMXAVG_STRUCT nMmxavg;
00484
00485 #ifdef rtlinux
00486
00487 static double etime()
00488 {
00489 RTIME now;
00490
00491 now = rt_get_time();
00492
00493 return ((double) now) / ((double) RT_TICKS_PER_SEC);
00494 }
00495
00496 #endif
00497
00498 static void reportError(const char *fmt, ...)
00499 {
00500 va_list args;
00501 char error[EMCMOT_ERROR_LEN];
00502
00503 va_start(args, fmt);
00504 vsprintf(error, fmt, args);
00505 va_end(args);
00506
00507 #if defined (rtlinux) && defined (RT_FIFO)
00508 rtf_put(EMCMOT_ERROR_RTF, error, EMCMOT_ERROR_LEN);
00509
00510 #else
00511 emcmotErrorPut(emcmotError, error);
00512
00513 #endif
00514 }
00515
00516
00517 #define XRANGE ((emcmotStatus->maxLimit[0] - emcmotStatus->minLimit[0]))
00518 #define YRANGE ((emcmotStatus->maxLimit[1] - emcmotStatus->minLimit[1]))
00519 #define ZRANGE ((emcmotStatus->maxLimit[2] - emcmotStatus->minLimit[2]))
00520
00521
00522
00523 static int inRange(EmcPose pos)
00524 {
00525 double joint[EMCMOT_MAX_AXIS];
00526 int axis;
00527
00528
00529 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
00530 {
00531 joint[axis] = 0.0;
00532 }
00533
00534
00535 inverseKinematics(pos, joint);
00536
00537 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
00538 {
00539 if (! GET_AXIS_ACTIVE_FLAG(axis))
00540 {
00541
00542 continue;
00543 }
00544
00545 if (joint[axis] > emcmotStatus->maxLimit[axis] ||
00546 joint[axis] < emcmotStatus->minLimit[axis])
00547 {
00548 return 0;
00549 }
00550 }
00551
00552
00553 return 1;
00554 }
00555
00556
00557
00558 static int checkLimits()
00559 {
00560 int axis;
00561
00562 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
00563 {
00564 if (! GET_AXIS_ACTIVE_FLAG(axis))
00565 {
00566
00567 continue;
00568 }
00569
00570 if (GET_AXIS_PSL_FLAG(axis) ||
00571 GET_AXIS_NSL_FLAG(axis) ||
00572 GET_AXIS_PHL_FLAG(axis) ||
00573 GET_AXIS_NHL_FLAG(axis))
00574 {
00575 return 0;
00576 }
00577 }
00578
00579 return 1;
00580 }
00581
00582
00583
00584
00585
00586 static int checkJog(int axis, double vel)
00587 {
00588 if (axis < 0 ||
00589 axis >= EMCMOT_MAX_AXIS)
00590 {
00591 return 0;
00592 }
00593
00594 if (vel > 0.0 &&
00595 (GET_AXIS_PSL_FLAG(axis) ||
00596 GET_AXIS_PHL_FLAG(axis)))
00597 {
00598 return 0;
00599 }
00600
00601 if (vel < 0.0 &&
00602 (GET_AXIS_NSL_FLAG(axis) ||
00603 GET_AXIS_NHL_FLAG(axis)))
00604 {
00605 return 0;
00606 }
00607
00608
00609 return 1;
00610 }
00611
00612
00613 static void setTrajCycleTime(double secs)
00614 {
00615 static int t;
00616
00617
00618 if (secs <= 0.0)
00619 {
00620 return;
00621 }
00622
00623
00624 emcmotStatus->interpolationRate =
00625 (int) (secs / emcmotStatus->servoCycleTime + 0.5);
00626
00627
00628 sqSetCycleTime(&queue, secs);
00629
00630
00631 for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00632 {
00633 tpSetCycleTime(&freeAxis[t], secs);
00634 cubicSetInterpolationRate(&cubic[t], emcmotStatus->interpolationRate);
00635 }
00636
00637
00638 emcmotStatus->trajCycleTime = secs;
00639 }
00640
00641
00642 static void setServoCycleTime(double secs)
00643 {
00644 static int t;
00645
00646
00647 if (secs <= 0.0)
00648 {
00649 return;
00650 }
00651
00652
00653 emcmotStatus->interpolationRate =
00654 (int) (emcmotStatus->trajCycleTime / secs + 0.5);
00655
00656
00657 for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00658 {
00659 cubicSetInterpolationRate(&cubic[t], emcmotStatus->interpolationRate);
00660 cubicSetSegmentTime(&cubic[t], secs);
00661 #ifndef STEPPER_MOTORS
00662 pidSetCycleTime(&emcmotStatus->pid[t], secs);
00663 #endif
00664 }
00665
00666
00667 emcmotStatus->servoCycleTime = secs;
00668 }
00669
00670
00671
00672
00673
00674 static int emcmotCommandHandler()
00675 {
00676 int axis;
00677 EmcPose jogPos;
00678 double saveVmax;
00679 #ifdef rtlinux
00680 #ifdef RT_FIFO
00681 int err;
00682 #endif
00683 #endif
00684 int valid;
00685
00686
00687
00688 #if defined (rtlinux) && defined (RT_FIFO)
00689 while ((err = rtf_get(EMCMOT_COMMAND_RTF, &emcmotCommandBuffer, sizeof(EMCMOT_COMMAND))) == sizeof(EMCMOT_COMMAND))
00690 {
00691
00692 #endif
00693
00694
00695 if (emcmotCommand->head != emcmotCommand->tail)
00696 {
00697 emcmotStatus->split++;
00698 return 0;
00699 }
00700
00701 if (emcmotCommand->commandNum != emcmotStatus->commandNumEcho)
00702 {
00703
00704 emcmotStatus->commandEcho = emcmotCommand->command;
00705 emcmotStatus->commandNumEcho = emcmotCommand->commandNum;
00706
00707
00708 emcmotStatus->commandStatus = EMCMOT_COMMAND_OK;
00709
00710
00711 if (emcmotStatus->logStarted &&
00712 emcmotStatus->logType == EMCMOT_LOG_TYPE_CMD)
00713 {
00714 ls.item.cmd.time = etime();
00715 ls.item.cmd.command = emcmotCommand->command;
00716 ls.item.cmd.commandNum = emcmotCommand->commandNum;
00717 #if defined (rtlinux) && defined (RT_FIFO)
00718 rtf_put(EMCMOT_LOG_RTF, &ls, sizeof(EMCMOT_LOG_STRUCT));
00719 #else
00720 emcmotLogAdd(emcmotLog, ls);
00721 #endif
00722 }
00723
00724
00725 switch (emcmotCommand->command)
00726 {
00727 case EMCMOT_FREE:
00728
00729
00730
00731
00732 coordinating = 0;
00733 break;
00734
00735 case EMCMOT_COORD:
00736
00737
00738
00739
00740 coordinating = 1;
00741 break;
00742
00743 case EMCMOT_SET_TRAJ_CYCLE_TIME:
00744
00745
00746
00747
00748
00749 setTrajCycleTime(emcmotCommand->cycleTime);
00750 break;
00751
00752 case EMCMOT_SET_SERVO_CYCLE_TIME:
00753
00754
00755
00756
00757
00758
00759 setServoCycleTime(emcmotCommand->cycleTime);
00760 #ifdef rtlinux
00761 rt_task_make_periodic(&emcmotTask,
00762 rt_get_time(),
00763 (RTIME) (RT_TICKS_PER_SEC *
00764 emcmotStatus->servoCycleTime));
00765 #ifdef STEPPER_MOTORS
00766
00767 rt_task_make_periodic(&smTask,
00768 rt_get_time(),
00769 ((RTIME) (RT_TICKS_PER_SEC *
00770 emcmotStatus->servoCycleTime)) >> 1);
00771 #endif
00772 #endif
00773 break;
00774
00775 case EMCMOT_SET_POSITION_LIMITS:
00776
00777
00778 axis = emcmotCommand->axis;
00779 if (axis < 0 ||
00780 axis >= EMCMOT_MAX_AXIS)
00781 {
00782 break;
00783 }
00784 emcmotStatus->minLimit[axis] = emcmotCommand->minLimit;
00785 emcmotStatus->maxLimit[axis] = emcmotCommand->maxLimit;
00786 break;
00787
00788 case EMCMOT_SET_OUTPUT_LIMITS:
00789
00790
00791 axis = emcmotCommand->axis;
00792 if (axis < 0 ||
00793 axis >= EMCMOT_MAX_AXIS)
00794 {
00795 break;
00796 }
00797
00798 emcmotStatus->minOutput[axis] = emcmotCommand->minLimit;
00799 emcmotStatus->maxOutput[axis] = emcmotCommand->maxLimit;
00800 break;
00801
00802 case EMCMOT_SET_OUTPUT_SCALE:
00803 axis = emcmotCommand->axis;
00804 if (axis < 0 ||
00805 axis >= EMCMOT_MAX_AXIS ||
00806 emcmotCommand->scale == 0)
00807 {
00808 break;
00809 }
00810 emcmotStatus->outputScale[axis] = emcmotCommand->scale;
00811 emcmotStatus->outputOffset[axis] = emcmotCommand->offset;
00812 break;
00813
00814 case EMCMOT_SET_INPUT_SCALE:
00815
00816
00817
00818
00819
00820
00821
00822 axis = emcmotCommand->axis;
00823 if (axis < 0 ||
00824 axis >= EMCMOT_MAX_AXIS ||
00825 emcmotCommand->scale == 0)
00826 {
00827 break;
00828 }
00829
00830
00831
00832 lastInput[axis] = lastInput[axis] * emcmotStatus->inputScale[axis] +
00833 emcmotStatus->inputOffset[axis];
00834 lastInput[axis] = (lastInput[axis] - emcmotCommand->offset) /
00835 emcmotCommand->scale;
00836
00837
00838 emcmotStatus->inputScale[axis] = emcmotCommand->scale;
00839 emcmotStatus->inputOffset[axis] = emcmotCommand->offset;
00840
00841
00842 smStepsPerUnit[axis] = emcmotCommand->scale;
00843
00844 break;
00845
00846 case EMCMOT_SET_MAX_FERROR:
00847 axis = emcmotCommand->axis;
00848 if (axis < 0 ||
00849 axis >= EMCMOT_MAX_AXIS ||
00850 emcmotCommand->maxFerror < 0.0)
00851 {
00852 break;
00853 }
00854 emcmotStatus->maxFerror[axis] =
00855 emcmotCommand->maxFerror;
00856 break;
00857
00858 case EMCMOT_JOG_CONT:
00859
00860
00861
00862
00863
00864 axis = emcmotCommand->axis;
00865 if (axis < 0 ||
00866 axis >= EMCMOT_MAX_AXIS)
00867 {
00868 break;
00869 }
00870
00871
00872 if (GET_MOTION_COORD_FLAG() != 0 ||
00873 ! GET_MOTION_INPOS_FLAG() ||
00874 ! GET_MOTION_ENABLE_FLAG())
00875 {
00876 SET_AXIS_ERROR_FLAG(axis, 1);
00877 break;
00878 }
00879
00880
00881 if (! checkJog(axis, emcmotCommand->vel))
00882 {
00883 SET_AXIS_ERROR_FLAG(axis, 1);
00884 break;
00885 }
00886
00887
00888 jogPos = emcmotStatus->pos;
00889
00890 switch (axis)
00891 {
00892 case 0:
00893 if (emcmotCommand->vel > 0.0)
00894 {
00895 if (GET_AXIS_HOMED_FLAG(axis))
00896 {
00897 jogPos.tran.x = emcmotStatus->maxLimit[axis];
00898 }
00899 else
00900 {
00901 jogPos.tran.x = emcmotStatus->pos.tran.x + XRANGE;
00902 }
00903 }
00904 else
00905 {
00906 if (GET_AXIS_HOMED_FLAG(axis))
00907 {
00908 jogPos.tran.x = emcmotStatus->minLimit[axis];
00909 }
00910 else
00911 {
00912 jogPos.tran.x = emcmotStatus->pos.tran.x - XRANGE;
00913 }
00914 }
00915 jogPos.tran.y = 0.0;
00916 jogPos.tran.z = 0.0;
00917 break;
00918
00919 case 1:
00920 if (emcmotCommand->vel > 0.0)
00921 {
00922 if (GET_AXIS_HOMED_FLAG(axis))
00923 {
00924 jogPos.tran.y = emcmotStatus->maxLimit[axis];
00925 }
00926 else
00927 {
00928 jogPos.tran.y = emcmotStatus->pos.tran.y + YRANGE;
00929 }
00930 }
00931 else
00932 {
00933 if (GET_AXIS_HOMED_FLAG(axis))
00934 {
00935 jogPos.tran.y = emcmotStatus->minLimit[axis];
00936 }
00937 else
00938 {
00939 jogPos.tran.y = emcmotStatus->pos.tran.y - YRANGE;
00940 }
00941 }
00942 jogPos.tran.z = 0.0;
00943 jogPos.tran.x = 0.0;
00944 break;
00945
00946 case 2:
00947 if (emcmotCommand->vel > 0.0)
00948 {
00949 if (GET_AXIS_HOMED_FLAG(axis))
00950 {
00951 jogPos.tran.z = emcmotStatus->maxLimit[axis];
00952 }
00953 else
00954 {
00955 jogPos.tran.z = emcmotStatus->pos.tran.z + ZRANGE;
00956 }
00957 }
00958 else
00959 {
00960 if (GET_AXIS_HOMED_FLAG(axis))
00961 {
00962 jogPos.tran.z = emcmotStatus->minLimit[axis];
00963 }
00964 else
00965 {
00966 jogPos.tran.z = emcmotStatus->pos.tran.z - ZRANGE;
00967 }
00968 }
00969 jogPos.tran.x = 0.0;
00970 jogPos.tran.y = 0.0;
00971 break;
00972
00973 default:
00974 break;
00975 }
00976
00977 saveVmax = freeAxis[axis].vMax;
00978 tpSetVmax(&freeAxis[axis], fabs(emcmotCommand->vel));
00979 tpAddLine(&freeAxis[axis], jogPos);
00980 tpSetVmax(&freeAxis[axis], saveVmax);
00981 SET_AXIS_ERROR_FLAG(axis, 0);
00982
00983 break;
00984
00985 case EMCMOT_JOG_INCR:
00986
00987
00988
00989 axis = emcmotCommand->axis;
00990 if (axis < 0 ||
00991 axis >= EMCMOT_MAX_AXIS)
00992 {
00993 break;
00994 }
00995
00996
00997 if (GET_MOTION_COORD_FLAG() != 0 ||
00998 ! GET_MOTION_INPOS_FLAG() ||
00999 ! GET_MOTION_ENABLE_FLAG())
01000 {
01001 SET_AXIS_ERROR_FLAG(axis, 1);
01002 break;
01003 }
01004
01005
01006 if (! checkJog(axis, emcmotCommand->vel))
01007 {
01008 SET_AXIS_ERROR_FLAG(axis, 1);
01009 break;
01010 }
01011
01012
01013 jogPos = emcmotStatus->pos;
01014
01015 switch (axis)
01016 {
01017 case 0:
01018 if (emcmotCommand->vel > 0.0)
01019 jogPos.tran.x += emcmotCommand->pos.tran.x;
01020 else
01021 jogPos.tran.x -= emcmotCommand->pos.tran.x;
01022 jogPos.tran.y = 0.0;
01023 jogPos.tran.z = 0.0;
01024 break;
01025
01026 case 1:
01027 if (emcmotCommand->vel > 0.0)
01028 jogPos.tran.y += emcmotCommand->pos.tran.y;
01029 else
01030 jogPos.tran.y -= emcmotCommand->pos.tran.y;
01031 jogPos.tran.z = 0.0;
01032 jogPos.tran.x = 0.0;
01033 break;
01034
01035 case 2:
01036 if (emcmotCommand->vel > 0.0)
01037 jogPos.tran.z += emcmotCommand->pos.tran.z;
01038 else
01039 jogPos.tran.z -= emcmotCommand->pos.tran.z;
01040 jogPos.tran.x = 0.0;
01041 jogPos.tran.y = 0.0;
01042 break;
01043
01044 default:
01045 break;
01046 }
01047
01048 saveVmax = freeAxis[axis].vMax;
01049 tpSetVmax(&freeAxis[axis], fabs(emcmotCommand->vel));
01050 tpAddLine(&freeAxis[axis], jogPos);
01051 tpSetVmax(&freeAxis[axis], saveVmax);
01052 SET_AXIS_ERROR_FLAG(axis, 0);
01053
01054 break;
01055
01056 case EMCMOT_JOG_ABS:
01057
01058
01059
01060 axis = emcmotCommand->axis;
01061 if (axis < 0 ||
01062 axis >= EMCMOT_MAX_AXIS)
01063 {
01064 break;
01065 }
01066
01067
01068 if (GET_MOTION_COORD_FLAG() != 0 ||
01069 ! GET_MOTION_INPOS_FLAG() ||
01070 ! GET_MOTION_ENABLE_FLAG())
01071 {
01072 SET_AXIS_ERROR_FLAG(axis, 1);
01073 break;
01074 }
01075
01076
01077 if (! checkJog(axis, emcmotCommand->vel))
01078 {
01079 SET_AXIS_ERROR_FLAG(axis, 1);
01080 break;
01081 }
01082
01083
01084 jogPos = emcmotStatus->pos;
01085
01086 switch (axis)
01087 {
01088 case 0:
01089 jogPos.tran.x = emcmotCommand->pos.tran.x;
01090 jogPos.tran.y = 0.0;
01091 jogPos.tran.z = 0.0;
01092 break;
01093
01094 case 1:
01095 jogPos.tran.y = emcmotCommand->pos.tran.y;
01096 jogPos.tran.z = 0.0;
01097 jogPos.tran.x = 0.0;
01098 break;
01099
01100 case 2:
01101 jogPos.tran.z = emcmotCommand->pos.tran.z;
01102 jogPos.tran.x = 0.0;
01103 jogPos.tran.y = 0.0;
01104 break;
01105
01106 default:
01107 break;
01108 }
01109
01110 saveVmax = freeAxis[axis].vMax;
01111 tpSetVmax(&freeAxis[axis], fabs(emcmotCommand->vel));
01112 tpAddLine(&freeAxis[axis], jogPos);
01113 tpSetVmax(&freeAxis[axis], saveVmax);
01114 SET_AXIS_ERROR_FLAG(axis, 0);
01115
01116 break;
01117
01118 case EMCMOT_SET_TERM_COND:
01119
01120
01121 break;
01122
01123 case EMCMOT_SET_LINE:
01124
01125
01126 if (! GET_MOTION_COORD_FLAG() ||
01127 ! GET_MOTION_ENABLE_FLAG())
01128 {
01129 reportError("Need to be enabled, in coord mode for linear move");
01130 emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_COMMAND;
01131 SET_MOTION_ERROR_FLAG(1);
01132 break;
01133 }
01134 else if (! inRange(emcmotCommand->pos))
01135 {
01136 reportError("Linear move %d out of range",
01137 emcmotCommand->id);
01138 emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
01139 sqAbort(&queue);
01140
01141 SET_MOTION_ERROR_FLAG(1);
01142 break;
01143 }
01144 else if (! checkLimits())
01145 {
01146 reportError("Can't do linear move with limits exceeded");
01147 emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
01148 sqAbort(&queue);
01149 SET_MOTION_ERROR_FLAG(1);
01150 break;
01151 }
01152
01153
01154 if ( -1 == sqAddLine( &queue, emcmotCommand->pos, \
01155 emcmotCommand->id ) )
01156 {
01157 reportError("Can't add linear move");
01158 emcmotStatus->commandStatus = EMCMOT_COMMAND_BAD_EXEC;
01159 sqAbort(&queue);
01160 SET_MOTION_ERROR_FLAG(1);
01161 break;
01162 }
01163 else
01164 {
01165 SET_MOTION_ERROR_FLAG(0);
01166 }
01167 break;
01168
01169 case EMCMOT_SET_CIRCLE:
01170
01171
01172 if (! GET_MOTION_COORD_FLAG() ||
01173 ! GET_MOTION_ENABLE_FLAG())
01174 {
01175 reportError("Need to be enabled, in coord mode for circular move");
01176 emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_COMMAND;
01177 SET_MOTION_ERROR_FLAG(1);
01178 break;
01179 }
01180 else if (! inRange(emcmotCommand->pos))
01181 {
01182 reportError("Circular move %d out of range",
01183 emcmotCommand->id);
01184 emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
01185 sqAbort(&queue);
01186
01187 SET_MOTION_ERROR_FLAG(1);
01188 break;
01189 }
01190 else if (! checkLimits())
01191 {
01192 reportError("Can't do circular move with limits exceeded");
01193 emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
01194 sqAbort(&queue);
01195
01196 SET_MOTION_ERROR_FLAG(1);
01197 break;
01198 }
01199
01200
01201 if ( -1 == sqAddCircle( &queue, emcmotCommand->pos,
01202 emcmotCommand->center, emcmotCommand->normal,
01203 emcmotCommand->turn, emcmotCommand->id ) )
01204 {
01205 reportError("Can't add circular move");
01206 emcmotStatus->commandStatus = EMCMOT_COMMAND_BAD_EXEC;
01207 sqAbort(&queue);
01208
01209 SET_MOTION_ERROR_FLAG(1);
01210 break;
01211 }
01212 else
01213 {
01214 SET_MOTION_ERROR_FLAG(0);
01215 }
01216 break;
01217
01218 case EMCMOT_SET_VEL:
01219
01220
01221 emcmotStatus->vel = emcmotCommand->vel;
01222 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
01223 {
01224 tpSetVmax(&freeAxis[axis], emcmotStatus->vel);
01225 }
01226 sqSetFeed(&queue, emcmotStatus->vel);
01227 break;
01228
01229
01230
01231 if (bigVel < 10.0 * emcmotCommand->vel)
01232 {
01233 bigVel = 10.0 * emcmotCommand->vel;
01234 }
01235 break;
01236
01237 case EMCMOT_SET_VEL_LIMIT:
01238
01239
01240 emcmotStatus->limitVel = emcmotCommand->vel;
01241 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
01242 {
01243 tpSetVlimit(&freeAxis[axis], emcmotStatus->limitVel);
01244 }
01245 sqSetVmax(&queue, emcmotStatus->limitVel);
01246
01247 bigVel = 10.0 * emcmotStatus->limitVel;
01248 break;
01249
01250 case EMCMOT_SET_HOMING_VEL:
01251
01252
01253
01254
01255
01256 axis = emcmotCommand->axis;
01257 if (axis < 0 ||
01258 axis >= EMCMOT_MAX_AXIS)
01259 {
01260 break;
01261 }
01262
01263 if (emcmotCommand->vel < 0.0)
01264 {
01265 emcmotStatus->homingVel[axis] = - emcmotCommand->vel;
01266 SET_AXIS_HOMING_POLARITY(axis, 0);
01267 }
01268 else
01269 {
01270 emcmotStatus->homingVel[axis] = emcmotCommand->vel;
01271 SET_AXIS_HOMING_POLARITY(axis, 1);
01272 }
01273 break;
01274
01275 case EMCMOT_SET_ACC:
01276
01277
01278 emcmotStatus->acc = emcmotCommand->acc;
01279 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
01280 {
01281 tpSetAmax(&freeAxis[axis], emcmotStatus->acc);
01282 }
01283 sqSetMaxAcc(&queue, emcmotStatus->acc);
01284 break;
01285
01286 case EMCMOT_PAUSE:
01287
01288
01289
01290 if ( 0 == coordinating )
01291 {
01292 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
01293 {
01294 tpPause(&freeAxis[axis]);
01295 }
01296 emcmotStatus->paused = 1;
01297 }
01298 else
01299 {
01300 if (-1 ==sqPause(&queue))
01301 {
01302 reportError("Can't pause");
01303 sqAbort(&queue);
01304 break;
01305 }
01306 emcmotStatus->paused= sqIsPaused(&queue);
01307 }
01308 break;
01309
01310 case EMCMOT_RESUME:
01311
01312
01313
01314 if ( 0 == coordinating )
01315 {
01316 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
01317 {
01318 tpResume(&freeAxis[axis]);
01319 }
01320 emcmotStatus->paused = 0;
01321 stepping = 0;
01322 }
01323 else
01324 {
01325 if (-1 == sqResume(&queue))
01326 {
01327 reportError("Can't resume");
01328 sqAbort(&queue);
01329 break;
01330 }
01331
01332 emcmotStatus->paused = sqIsPaused(&queue);
01333 stepping = sqIsStepping(&queue);
01334 }
01335
01336 break;
01337
01338 case EMCMOT_STEP:
01339
01340
01341 if ( 0 == coordinating )
01342 {
01343 idForStep = emcmotStatus->id;
01344 stepping = 1;
01345 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
01346 {
01347 tpResume(&freeAxis[axis]);
01348 }
01349 emcmotStatus->paused = 0;
01350 }
01351 else
01352 {
01353 if (-1 == sqStep(&queue) )
01354 {
01355 reportError("Can't step");
01356 sqAbort(&queue);
01357 break;
01358 }
01359 }
01360
01361 break;
01362
01363 case EMCMOT_SCALE:
01364
01365
01366 if (emcmotCommand->scale < 0.0)
01367 {
01368 emcmotCommand->scale = 0.0;
01369 }
01370 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
01371 {
01372 tpSetVscale(&freeAxis[axis], emcmotCommand->scale);
01373 }
01374 if (-1 == sqSetFeedOverride(&queue, emcmotCommand->scale))
01375 {
01376 reportError("Can't set new feed");
01377 sqAbort(&queue);
01378 break;
01379 }
01380
01381
01382 break;
01383
01384 case EMCMOT_ABORT:
01385
01386
01387
01388 if (GET_MOTION_COORD_FLAG())
01389 {
01390 sqAbort(&queue);
01391 SET_MOTION_ERROR_FLAG(0);
01392 }
01393 else
01394 {
01395
01396 axis = emcmotCommand->axis;
01397 if (axis < 0 ||
01398 axis >= EMCMOT_MAX_AXIS)
01399 {
01400 break;
01401 }
01402 tpAbort(&freeAxis[axis]);
01403 SET_AXIS_HOMING_FLAG(axis, 0);
01404 SET_AXIS_ERROR_FLAG(axis, 0);
01405 }
01406 break;
01407
01408 case EMCMOT_DISABLE:
01409
01410
01411
01412
01413 enabling = 0;
01414 break;
01415
01416 case EMCMOT_ENABLE:
01417
01418
01419
01420
01421 enabling = 1;
01422 break;
01423
01424 case EMCMOT_SET_PID:
01425
01426 axis = emcmotCommand->axis;
01427 if (axis < 0 ||
01428 axis >= EMCMOT_MAX_AXIS)
01429 {
01430 break;
01431 }
01432 pidSetGains(&emcmotStatus->pid[axis],
01433 emcmotCommand->pid);
01434 break;
01435
01436 case EMCMOT_ACTIVATE_AXIS:
01437
01438
01439
01440 axis = emcmotCommand->axis;
01441 if (axis < 0 ||
01442 axis >= EMCMOT_MAX_AXIS)
01443 {
01444 break;
01445 }
01446 SET_AXIS_ACTIVE_FLAG(axis, 1);
01447 break;
01448
01449 case EMCMOT_DEACTIVATE_AXIS:
01450
01451
01452
01453 axis = emcmotCommand->axis;
01454 if (axis < 0 ||
01455 axis >= EMCMOT_MAX_AXIS)
01456 {
01457 break;
01458 }
01459 SET_AXIS_ACTIVE_FLAG(axis, 0);
01460 break;
01461
01462 case EMCMOT_ENABLE_AMPLIFIER:
01463
01464
01465 axis = emcmotCommand->axis;
01466 if (axis < 0 ||
01467 axis >= EMCMOT_MAX_AXIS)
01468 {
01469 break;
01470 }
01471 extAmpEnable(axis, GET_AXIS_ENABLE_POLARITY(axis));
01472 break;
01473
01474 case EMCMOT_DISABLE_AMPLIFIER:
01475
01476
01477
01478 axis = emcmotCommand->axis;
01479 if (axis < 0 ||
01480 axis >= EMCMOT_MAX_AXIS)
01481 {
01482 break;
01483 }
01484 extAmpEnable(axis, ! GET_AXIS_ENABLE_POLARITY(axis));
01485 break;
01486
01487 case EMCMOT_OPEN_LOG:
01488
01489 axis = emcmotCommand->axis;
01490 valid = 0;
01491 if (emcmotCommand->logSize > 0 &&
01492 emcmotCommand->logSize <= EMCMOT_LOG_MAX)
01493 {
01494
01495 switch (emcmotCommand->logType)
01496 {
01497 case EMCMOT_LOG_TYPE_AXIS_POS:
01498 if (axis >= 0 &&
01499 axis < EMCMOT_MAX_AXIS)
01500 {
01501 loggingAxis = axis;
01502 valid = 1;
01503 }
01504 break;
01505
01506 default:
01507 valid = 1;
01508 break;
01509 }
01510 }
01511
01512 if (valid)
01513 {
01514
01515 #if defined (rtlinux) && defined (RT_FIFO)
01516 if (-1 == rtf_create(EMCMOT_LOG_RTF, emcmotCommand->logSize * sizeof(EMCMOT_LOG_STRUCT)))
01517 {
01518
01519 break;
01520 }
01521 #else
01522 emcmotLogInit(emcmotLog,
01523 emcmotCommand->logType,
01524 emcmotCommand->logSize);
01525 #endif
01526 emcmotStatus->logOpen = 1;
01527 emcmotStatus->logStarted = 0;
01528 emcmotStatus->logSize = emcmotCommand->logSize;
01529 emcmotStatus->logSkip = emcmotCommand->logSkip;
01530 emcmotStatus->logType = emcmotCommand->logType;
01531 }
01532 break;
01533
01534 case EMCMOT_START_LOG:
01535
01536 if (emcmotStatus->logOpen)
01537 {
01538 emcmotStatus->logStarted = 1;
01539 logSkip = 0;
01540 }
01541 break;
01542
01543 case EMCMOT_STOP_LOG:
01544
01545 emcmotStatus->logStarted = 0;
01546 break;
01547
01548 case EMCMOT_CLOSE_LOG:
01549 #if defined (rtlinux) && defined (RT_FIFO)
01550 rtf_destroy(EMCMOT_LOG_RTF);
01551 #endif
01552 emcmotStatus->logOpen = 0;
01553 emcmotStatus->logStarted = 0;
01554 emcmotStatus->logSize = 0;
01555 emcmotStatus->logSkip = 0;
01556 emcmotStatus->logType = 0;
01557 break;
01558
01559 case EMCMOT_DAC_OUT:
01560
01561
01562 axis = emcmotCommand->axis;
01563 if (axis < 0 ||
01564 axis >= EMCMOT_MAX_AXIS)
01565 {
01566 break;
01567 }
01568 emcmotStatus->output[axis] = emcmotCommand->dacOut;
01569 break;
01570
01571 case EMCMOT_HOME:
01572
01573
01574
01575 axis = emcmotCommand->axis;
01576 if (GET_MOTION_COORD_FLAG() != 0 ||
01577 ! GET_MOTION_ENABLE_FLAG())
01578 {
01579 break;
01580 }
01581 if (axis < 0 ||
01582 axis >= EMCMOT_MAX_AXIS)
01583 {
01584 break;
01585 }
01586
01587 jogPos = emcmotStatus->pos;
01588
01589 switch (axis)
01590 {
01591 case 0:
01592 if (GET_AXIS_HOMING_POLARITY(axis))
01593 {
01594 jogPos.tran.x += 2.0 * XRANGE;
01595 }
01596 else
01597 {
01598 jogPos.tran.x -= 2.0 * XRANGE;
01599 }
01600 jogPos.tran.y = 0.0;
01601 jogPos.tran.z = 0.0;
01602 break;
01603
01604 case 1:
01605 if (GET_AXIS_HOMING_POLARITY(axis))
01606 {
01607 jogPos.tran.y += 2.0 * YRANGE;
01608 }
01609 else
01610 {
01611 jogPos.tran.y -= 2.0 * YRANGE;
01612 }
01613 jogPos.tran.z = 0.0;
01614 jogPos.tran.x = 0.0;
01615 break;
01616
01617 case 2:
01618 if (GET_AXIS_HOMING_POLARITY(axis))
01619 {
01620 jogPos.tran.z += 2.0 * ZRANGE;
01621 }
01622 else
01623 {
01624 jogPos.tran.z -= 2.0 * ZRANGE;
01625 }
01626 jogPos.tran.x = 0.0;
01627 jogPos.tran.y = 0.0;
01628 break;
01629
01630 default:
01631 break;
01632 }
01633
01634 saveVmax = freeAxis[axis].vMax;
01635 tpSetVmax(&freeAxis[axis], emcmotStatus->homingVel[axis]);
01636 tpAddLine(&freeAxis[axis], jogPos);
01637 tpSetVmax(&freeAxis[axis], saveVmax);
01638 waitingForLatch[axis] = 1;
01639 SET_AXIS_HOMING_FLAG(axis, 1);
01640 SET_AXIS_HOMED_FLAG(axis, 0);
01641 break;
01642
01643 case EMCMOT_ENABLE_WATCHDOG:
01644 wdEnable = 1;
01645 if (emcmotCommand->wdWait < 0)
01646 {
01647 wdWait = 0;
01648 }
01649 else
01650 {
01651 wdWait = emcmotCommand->wdWait;
01652 }
01653 wdCount = wdWait;
01654 break;
01655
01656 case EMCMOT_DISABLE_WATCHDOG:
01657 wdEnable = 0;
01658 break;
01659
01660 case EMCMOT_SET_POLARITY:
01661 axis = emcmotCommand->axis;
01662 if (axis < 0 ||
01663 axis >= EMCMOT_MAX_AXIS)
01664 {
01665 break;
01666 }
01667 if (emcmotCommand->level)
01668 {
01669
01670 emcmotStatus->axisPolarity[axis] |= emcmotCommand->axisFlag;
01671 }
01672 else
01673 {
01674
01675 emcmotStatus->axisPolarity[axis] &= ~emcmotCommand->axisFlag;
01676 }
01677 break;
01678
01679 default:
01680 reportError("Unrecognized command %d", emcmotCommand->command);
01681 emcmotStatus->commandStatus = EMCMOT_COMMAND_UNKNOWN_COMMAND;
01682 break;
01683 }
01684 }
01685
01686 #if defined (rtlinux) && defined (RT_FIFO)
01687 }
01688
01689 if (err != 0)
01690 {
01691 return -1;
01692 }
01693
01694 #endif
01695
01696 return 0;
01697 }
01698
01699 #ifdef STEPPER_MOTORS
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710 static unsigned char fpInUse = 0;
01711
01712 #endif
01713
01714
01715
01716
01717
01718
01719
01720
01721 static void emcmotController(int arg)
01722 {
01723 double start, end, delta;
01724 int homeFlag;
01725 int axis;
01726 int isLimit;
01727 int whichCycle;
01728 int fault;
01729 double thisFerror[EMCMOT_MAX_AXIS];
01730
01731 #ifdef rtlinux
01732 for (;;)
01733 {
01734 #endif
01735
01736 #ifdef STEPPER_MOTORS
01737 if (fpInUse)
01738 {
01739 rt_task_wait();
01740 continue;
01741 }
01742 #endif
01743
01744 #ifdef rtlinux
01745
01746 if (wdEnable &&
01747 wdCount-- <= 0)
01748 {
01749 soundByte = inb(SOUND_PORT);
01750 soundByte &= SOUND_MASK;
01751 toggle = !toggle;
01752 if (toggle)
01753 soundByte |= ~SOUND_MASK;
01754 outb(soundByte, SOUND_PORT);
01755 wdCount = wdWait;
01756 }
01757 #endif
01758
01759
01760 emcmotStatus->head++;
01761
01762
01763 start = etime();
01764
01765
01766
01767 #ifndef RT_FIFO
01768 emcmotCommandHandler();
01769
01770 #endif
01771
01772
01773 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
01774 {
01775 oldInput[axis] = emcmotStatus->input[axis];
01776 oldJointPos[axis] = jointPos[axis];
01777 }
01778
01779
01780
01781
01782 #ifdef STEPPER_MOTORS
01783 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
01784 {
01785 rawInput[axis] = (double) smStepsAccum[axis];
01786 }
01787 #else
01788 extEncoderReadAll(EMCMOT_MAX_AXIS, rawInput);
01789 #endif
01790
01791
01792 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
01793 {
01794
01795
01796
01797 emcmotStatus->input[axis] =
01798 (rawInput[axis] - emcmotStatus->inputOffset[axis]) /
01799 emcmotStatus->inputScale[axis];
01800
01801 #ifndef STEPPER_MOTORS
01802
01803 if (fabs(emcmotStatus->input[axis] - lastInput[axis]) /
01804 emcmotStatus->servoCycleTime > bigVel) {
01805
01806 emcmotStatus->input[axis] = lastInput[axis];
01807 }
01808 #endif
01809 lastInput[axis] = emcmotStatus->input[axis];
01810
01811
01812 SET_AXIS_PHL_FLAG(axis, 0);
01813 SET_AXIS_NHL_FLAG(axis, 0);
01814
01815
01816 extMaxLimitSwitchRead(axis, &isLimit);
01817
01818
01819 if (isLimit == GET_AXIS_PHL_POLARITY(axis))
01820 {
01821 if (++maxLimitSwitchCount[axis] > LIMIT_SWITCH_DEBOUNCE)
01822 {
01823
01824 SET_AXIS_PHL_FLAG(axis, 1);
01825 maxLimitSwitchCount[axis] = LIMIT_SWITCH_DEBOUNCE;
01826 }
01827 }
01828 else
01829 {
01830 maxLimitSwitchCount[axis] = 0;
01831 }
01832
01833
01834 extMinLimitSwitchRead(axis, &isLimit);
01835
01836
01837 if (isLimit == GET_AXIS_NHL_POLARITY(axis))
01838 {
01839 if (++minLimitSwitchCount[axis] > LIMIT_SWITCH_DEBOUNCE)
01840 {
01841
01842 SET_AXIS_NHL_FLAG(axis, 1);
01843 minLimitSwitchCount[axis] = LIMIT_SWITCH_DEBOUNCE;
01844 }
01845 }
01846 else
01847 {
01848 minLimitSwitchCount[axis] = 0;
01849 }
01850
01851
01852 extHomeSwitchRead(axis, &homeFlag);
01853 SET_AXIS_HOME_SWITCH_FLAG(axis, homeFlag == GET_AXIS_HOME_SWITCH_POLARITY(axis));
01854
01855
01856 extAmpFault(axis, &fault);
01857 SET_AXIS_FAULT_FLAG(axis, fault == GET_AXIS_FAULT_POLARITY(axis));
01858
01859 }
01860
01861
01862
01863
01864 if (! enabling &&
01865 GET_MOTION_ENABLE_FLAG())
01866 {
01867
01868 sqClearQueue(&queue);
01869 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
01870 {
01871 tpClear(&freeAxis[axis]);
01872 cubicDrain(&cubic[axis]);
01873 if (GET_AXIS_ACTIVE_FLAG(axis))
01874 {
01875 extAmpEnable(axis,
01876 ! GET_AXIS_ENABLE_POLARITY(axis));
01877 SET_AXIS_ENABLE_FLAG(axis, 0);
01878 SET_AXIS_HOMING_FLAG(axis, 0);
01879 emcmotStatus->output[axis] = 0.0;
01880 }
01881 }
01882
01883
01884 SET_MOTION_ENABLE_FLAG(0);
01885 }
01886
01887
01888 if (enabling &&
01889 ! GET_MOTION_ENABLE_FLAG())
01890 {
01891 sqSetPos(&queue, emcmotStatus->pos);
01892 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
01893 {
01894 tpSetPos(&freeAxis[axis], emcmotStatus->pos);
01895 pidReset(&emcmotStatus->pid[axis]);
01896 if (GET_AXIS_ACTIVE_FLAG(axis))
01897 {
01898 extAmpEnable(axis,
01899 GET_AXIS_ENABLE_POLARITY(axis));
01900 SET_AXIS_ENABLE_FLAG(axis, 1);
01901 }
01902 SET_AXIS_ERROR_FLAG(axis, 0);
01903 }
01904
01905
01906 SET_MOTION_ENABLE_FLAG(1);
01907 SET_MOTION_ERROR_FLAG(0);
01908 }
01909
01910
01911 if (coordinating &&
01912 ! GET_MOTION_COORD_FLAG())
01913 {
01914 if (GET_MOTION_INPOS_FLAG())
01915 {
01916
01917 sqSetPos(&queue, emcmotStatus->pos);
01918
01919 SET_MOTION_COORD_FLAG(1);
01920 SET_MOTION_ERROR_FLAG(0);
01921 }
01922 else
01923 {
01924
01925 coordinating = 0;
01926 }
01927 }
01928
01929
01930 if (! coordinating &&
01931 GET_MOTION_COORD_FLAG())
01932 {
01933 if (GET_MOTION_INPOS_FLAG())
01934 {
01935
01936 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
01937 {
01938 tpSetPos(&freeAxis[axis], emcmotStatus->pos);
01939 }
01940 SET_MOTION_COORD_FLAG(0);
01941 }
01942 else
01943 {
01944
01945 coordinating = 1;
01946 }
01947 }
01948
01949
01950 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
01951 {
01952 if (GET_AXIS_HOMING_FLAG(axis))
01953 {
01954 if (tpIsDone(&freeAxis[axis]))
01955 {
01956
01957 emcmotStatus->inputOffset[axis] = saveLatch[axis];
01958
01959
01960
01961 emcmotStatus->input[axis] =
01962 (rawInput[axis] - emcmotStatus->inputOffset[axis]) /
01963 emcmotStatus->inputScale[axis];
01964 lastInput[axis] = emcmotStatus->input[axis];
01965
01966
01967 if (axis == 0)
01968 emcmotStatus->pos.tran.x = 0;
01969 else if (axis == 1)
01970 emcmotStatus->pos.tran.y = 0;
01971 else if (axis == 2)
01972 emcmotStatus->pos.tran.z = 0;
01973
01974
01975 tpSetPos(&freeAxis[axis], emcmotStatus->pos);
01976 cubicDrain(&cubic[0]);
01977 cubicDrain(&cubic[1]);
01978 cubicDrain(&cubic[2]);
01979 SET_AXIS_HOMING_FLAG(axis, 0);
01980 SET_AXIS_HOMED_FLAG(axis, 1);
01981 }
01982 }
01983 }
01984
01985
01986
01987
01988
01989
01990
01991 whichCycle = 0;
01992 if (GET_MOTION_ENABLE_FLAG())
01993 {
01994
01995 whichCycle = 1;
01996
01997 while (cubicNeedNextPoint(&cubic[0]))
01998 {
01999
02000 whichCycle = 2;
02001
02002
02003 oldPos = emcmotStatus->pos;
02004
02005
02006 if (GET_MOTION_COORD_FLAG() == 1)
02007 {
02008
02009 if (-1 ==sqRunCycle(&queue))
02010 {
02011 reportError("Runcycle error");
02012 sqAbort(&queue);
02013 }
02014 sqGetPosition(&queue,&emcmotStatus->pos);
02015 }
02016 else
02017 {
02018
02019 tpRunCycle(&freeAxis[0]);
02020 tpRunCycle(&freeAxis[1]);
02021 tpRunCycle(&freeAxis[2]);
02022 emcmotStatus->pos.tran.x = tpGetPos(&freeAxis[0]).tran.x;
02023 emcmotStatus->pos.tran.y = tpGetPos(&freeAxis[1]).tran.y;
02024 emcmotStatus->pos.tran.z = tpGetPos(&freeAxis[2]).tran.z;
02025 }
02026
02027
02028
02029
02030 newVel.tran.x = emcmotStatus->pos.tran.x - oldPos.tran.x;
02031 newVel.tran.y = emcmotStatus->pos.tran.y - oldPos.tran.y;
02032 newVel.tran.z = emcmotStatus->pos.tran.z - oldPos.tran.z;
02033 oldPos = emcmotStatus->pos;
02034
02035 newAcc.tran.x = newVel.tran.x - oldVel.tran.x;
02036 newAcc.tran.y = newVel.tran.y - oldVel.tran.y;
02037 newAcc.tran.z = newVel.tran.z - oldVel.tran.z;
02038 oldVel = newVel;
02039
02040
02041 logIt = 0;
02042 if (emcmotStatus->logStarted &&
02043 emcmotStatus->logSkip >= 0) {
02044
02045
02046 ls.type = emcmotStatus->logType;
02047
02048
02049 switch (emcmotStatus->logType) {
02050
02051 case EMCMOT_LOG_TYPE_TRAJ_POS:
02052 if (logSkip-- <= 0) {
02053 ls.item.trajPos.time = start;
02054 ls.item.trajPos.pos = emcmotStatus->pos.tran;
02055 logSkip = emcmotStatus->logSkip;
02056 logIt = 1;
02057 }
02058 break;
02059
02060 case EMCMOT_LOG_TYPE_TRAJ_VEL:
02061 if (logSkip-- <= 0) {
02062 ls.item.trajVel.time = start;
02063 ls.item.trajVel.vel = newVel.tran;
02064
02065 ls.item.trajVel.mag = sqGetVel(&queue);
02066 logSkip = emcmotStatus->logSkip;
02067 logIt = 1;
02068 }
02069 break;
02070
02071 case EMCMOT_LOG_TYPE_TRAJ_ACC:
02072 if (logSkip-- <= 0) {
02073 ls.item.trajAcc.time = start;
02074 ls.item.trajAcc.acc = newAcc.tran;
02075 pmCartMag(newAcc.tran, &ls.item.trajAcc.mag);
02076 logSkip = emcmotStatus->logSkip;
02077 logIt = 1;
02078 }
02079 break;
02080
02081 default:
02082 break;
02083 }
02084
02085
02086 #if defined (rtlinux) && defined (RT_FIFO)
02087 if (logIt) {
02088 rtf_put(EMCMOT_LOG_RTF, &ls, sizeof(EMCMOT_LOG_STRUCT));
02089
02090 logIt = 0;
02091 }
02092 #else
02093 if (logIt) {
02094 emcmotLogAdd(emcmotLog, ls);
02095 emcmotStatus->logPoints = emcmotLog->howmany;
02096 logIt = 0;
02097 }
02098 #endif
02099 }
02100
02101
02102 inverseKinematics(emcmotStatus->pos, trajPos);
02103 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
02104 {
02105 cubicAddPoint(&cubic[axis], trajPos[axis]);
02106 }
02107
02108
02109 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
02110 {
02111
02112 SET_AXIS_NSL_FLAG(axis, 0);
02113 SET_AXIS_PSL_FLAG(axis, 0);
02114
02115
02116
02117
02118
02119 if (GET_AXIS_NHL_FLAG(axis) ||
02120 GET_AXIS_PHL_FLAG(axis) ||
02121 (GET_AXIS_HOMED_FLAG(axis) &&
02122 (trajPos[axis] > emcmotStatus->maxLimit[axis] ||
02123 trajPos[axis] < emcmotStatus->minLimit[axis])) )
02124 {
02125
02126 SET_AXIS_ERROR_FLAG(axis, 1);
02127
02128
02129 if (GET_AXIS_HOMED_FLAG(axis) &&
02130 trajPos[axis] < emcmotStatus->minLimit[axis])
02131 {
02132 SET_AXIS_NSL_FLAG(axis, 1);
02133 }
02134 else if (GET_AXIS_HOMED_FLAG(axis) &&
02135 trajPos[axis] > emcmotStatus->maxLimit[axis])
02136 {
02137 SET_AXIS_PSL_FLAG(axis, 1);
02138 }
02139
02140
02141 if (! wasOnLimit[axis])
02142 {
02143 if (GET_MOTION_COORD_FLAG() == 1)
02144 {
02145 sqAbort(&queue);
02146 }
02147 else if (GET_MOTION_COORD_FLAG() == 0)
02148 {
02149 tpAbort(&freeAxis[axis]);
02150 }
02151 wasOnLimit[axis] = 1;
02152 }
02153 }
02154 else
02155 {
02156 wasOnLimit[axis] = 0;
02157 }
02158 }
02159 }
02160
02161
02162 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
02163 {
02164
02165 jointPos[axis] = cubicInterpolate(&cubic[axis], 0, 0, 0, 0);
02166
02167
02168 if (GET_AXIS_ACTIVE_FLAG(axis))
02169 {
02170 #ifndef STEPPER_MOTORS
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185 emcmotStatus->output[axis] =
02186 pidRunCycle(&emcmotStatus->pid[axis],
02187 emcmotStatus->input[axis],
02188 jointPos[axis]);
02189 #endif
02190
02191
02192
02193
02194
02195
02196
02197
02198 thisFerror[axis] = jointPos[axis] - emcmotStatus->input[axis];
02199
02200 if (emcmotStatus->ferror[axis] < fabs(thisFerror[axis]))
02201 {
02202 emcmotStatus->ferror[axis] = fabs(thisFerror[axis]);
02203 }
02204
02205 if (thisFerror[axis] > emcmotStatus->maxFerror[axis])
02206 {
02207
02208 SET_AXIS_ERROR_FLAG(axis, 1);
02209 SET_AXIS_FERROR_FLAG(axis, 1);
02210 if (enabling)
02211 {
02212
02213 reportError("Axis %d following error", axis);
02214 }
02215 enabling = 0;
02216 }
02217 else
02218 {
02219 SET_AXIS_FERROR_FLAG(axis, 0);
02220 }
02221 }
02222 else
02223 {
02224
02225
02226 }
02227
02228 #ifndef STEPPER_MOTORS
02229
02230
02231
02232
02233
02234
02235
02236 if (emcmotStatus->output[axis] < emcmotStatus->minOutput[axis])
02237 {
02238 emcmotStatus->output[axis] = emcmotStatus->minOutput[axis];
02239 }
02240 else if (emcmotStatus->output[axis] > emcmotStatus->maxOutput[axis])
02241 {
02242 emcmotStatus->output[axis] = emcmotStatus->maxOutput[axis];
02243 }
02244 #endif
02245
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259 if (waitingForLatch[axis])
02260 {
02261 if (GET_AXIS_HOME_SWITCH_FLAG(axis))
02262 {
02263
02264 #ifdef STEPPER_MOTORS
02265
02266 latchFlag[axis] = 1;
02267 #else
02268 extEncoderResetIndex(axis);
02269 extEncoderReadLatch(axis, &latchFlag[axis]);
02270 #endif
02271 if (latchFlag[axis])
02272 {
02273
02274 saveLatch[axis] = rawInput[axis];
02275 waitingForLatch[axis] = 0;
02276
02277
02278 tpAbort(&freeAxis[axis]);
02279 }
02280 }
02281 }
02282
02283 }
02284
02285 }
02286
02287 else
02288 {
02289
02290 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
02291 {
02292 jointPos[axis] = emcmotStatus->input[axis];
02293 }
02294
02295
02296 forwardKinematics(jointPos, &emcmotStatus->pos);
02297
02298 }
02299
02300 #ifndef STEPPER_MOTORS
02301
02302
02303 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
02304 {
02305 rawOutput[axis] =
02306 (emcmotStatus->output[axis] - emcmotStatus->outputOffset[axis]) /
02307 emcmotStatus->outputScale[axis];
02308 }
02309
02310
02311
02312
02313
02314
02315
02316 extDacWriteAll(EMCMOT_MAX_AXIS, rawOutput);
02317 #endif
02318
02319
02320
02321
02322
02323 forwardKinematics(emcmotStatus->input, &emcmotStatus->actualPos);
02324
02325
02326 emcmotStatus->heartbeat++;
02327
02328
02329 emcmotStatus->depth = sqGetDepth(&queue);
02330 emcmotStatus->activeDepth = sqGetDepth(&queue);
02331 emcmotStatus->qVscale = queue.feedOverrideFactor;
02332 emcmotStatus->id= sqGetID(&queue);
02333 emcmotStatus->queueFull = sqIsQueueFull(&queue);
02334
02335
02336
02337 SET_MOTION_INPOS_FLAG(0);
02338 if (sqIsDone(&queue))
02339 {
02340 SET_MOTION_INPOS_FLAG(1);
02341 }
02342
02343
02344 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
02345 {
02346 emcmotStatus->axVscale[axis] = freeAxis[axis].vScale;
02347
02348 SET_AXIS_INPOS_FLAG(axis, 0);
02349 if (tpIsDone(&freeAxis[axis]))
02350 {
02351 SET_AXIS_INPOS_FLAG(axis, 1);
02352 }
02353 }
02354
02355
02356
02357
02358 if (!coordinating && stepping && idForStep != emcmotStatus->id)
02359 {
02360 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
02361 {
02362 tpPause(&freeAxis[axis]);
02363 }
02364
02365 stepping = 0;
02366 emcmotStatus->paused = 1;
02367 }
02368
02369
02370 end = etime();
02371 delta = end - start;
02372 emcmotStatus->computeTime = delta;
02373 if (2 == whichCycle)
02374 {
02375
02376 mmxavgAdd(&tMmxavg, delta);
02377 emcmotStatus->tMin = mmxavgMin(&tMmxavg);
02378 emcmotStatus->tMax = mmxavgMax(&tMmxavg);
02379 emcmotStatus->tAvg = mmxavgAvg(&tMmxavg);
02380 }
02381 else if (1 == whichCycle)
02382 {
02383
02384 mmxavgAdd(&sMmxavg, delta);
02385 emcmotStatus->sMin = mmxavgMin(&sMmxavg);
02386 emcmotStatus->sMax = mmxavgMax(&sMmxavg);
02387 emcmotStatus->sAvg = mmxavgAvg(&sMmxavg);
02388 }
02389 else
02390 {
02391
02392 mmxavgAdd(&nMmxavg, delta);
02393 emcmotStatus->nMin = mmxavgMin(&nMmxavg);
02394 emcmotStatus->nMax = mmxavgMax(&nMmxavg);
02395 emcmotStatus->nAvg = mmxavgAvg(&nMmxavg);
02396 }
02397
02398
02399 logIt = 0;
02400 if (emcmotStatus->logStarted &&
02401 emcmotStatus->logSkip >= 0) {
02402
02403
02404 ls.type = emcmotStatus->logType;
02405
02406
02407 switch (ls.type) {
02408
02409 case EMCMOT_LOG_TYPE_AXIS_POS:
02410 if (logSkip-- <= 0) {
02411 ls.item.axisPos.time = end;
02412 ls.item.axisPos.input = emcmotStatus->input[loggingAxis];
02413 ls.item.axisPos.output = jointPos[loggingAxis];
02414 logSkip = emcmotStatus->logSkip;
02415 logIt = 1;
02416 }
02417 break;
02418
02419 case EMCMOT_LOG_TYPE_ALL_INPOS:
02420 if (logSkip-- <= 0) {
02421 ls.item.allInpos.time = end;
02422 for (axis = 0;
02423 axis < EMCMOT_LOG_NUM_AXES &&
02424 axis < EMCMOT_MAX_AXIS;
02425 axis++) {
02426 ls.item.allInpos.input[axis] = emcmotStatus->input[axis];
02427 }
02428 logSkip = emcmotStatus->logSkip;
02429 logIt = 1;
02430 }
02431 break;
02432
02433 case EMCMOT_LOG_TYPE_ALL_OUTPOS:
02434 if (logSkip-- <= 0) {
02435 ls.item.allOutpos.time = end;
02436 for (axis = 0;
02437 axis < EMCMOT_LOG_NUM_AXES &&
02438 axis < EMCMOT_MAX_AXIS;
02439 axis++) {
02440 ls.item.allOutpos.output[axis] = jointPos[axis];
02441 }
02442 logSkip = emcmotStatus->logSkip;
02443 logIt = 1;
02444 }
02445 break;
02446
02447 case EMCMOT_LOG_TYPE_AXIS_VEL:
02448 if (logSkip-- <= 0) {
02449 ls.item.axisVel.time = end;
02450 ls.item.axisVel.cmdVel = jointPos[loggingAxis] -
02451 oldJointPos[loggingAxis];
02452 ls.item.axisVel.actVel = emcmotStatus->input[loggingAxis] -
02453 oldInput[loggingAxis];
02454 logSkip = emcmotStatus->logSkip;
02455 logIt = 1;
02456 }
02457 break;
02458
02459 case EMCMOT_LOG_TYPE_ALL_FERROR:
02460 if (logSkip-- <= 0) {
02461 ls.item.allFerror.time = end;
02462 for (axis = 0;
02463 axis < EMCMOT_LOG_NUM_AXES &&
02464 axis < EMCMOT_MAX_AXIS;
02465 axis++) {
02466 ls.item.allFerror.ferror[axis] = thisFerror[axis];
02467 }
02468 logSkip = emcmotStatus->logSkip;
02469 logIt = 1;
02470 }
02471 break;
02472
02473 default:
02474 break;
02475 }
02476
02477
02478 #if defined (rtlinux) && defined (RT_FIFO)
02479 if (logIt) {
02480 rtf_put(EMCMOT_LOG_RTF, &ls, sizeof(EMCMOT_LOG_STRUCT));
02481
02482 logIt = 0;
02483 }
02484 #else
02485 if (logIt) {
02486 emcmotLogAdd(emcmotLog, ls);
02487 emcmotStatus->logPoints = emcmotLog->howmany;
02488 logIt = 0;
02489 }
02490 #endif
02491 }
02492
02493
02494 emcmotStatus->tail = emcmotStatus->head;
02495
02496
02497
02498 #if defined (rtlinux) && defined (RT_FIFO)
02499
02500 rtf_put(EMCMOT_STATUS_RTF, &emcmotStatusBuffer, sizeof(EMCMOT_STATUS));
02501
02502 #endif
02503
02504 #ifdef rtlinux
02505
02506 rt_task_wait();
02507 }
02508 #endif
02509 }
02510
02511 #ifdef STEPPER_MOTORS
02512
02513 static void smController(int arg)
02514 {
02515 int axis;
02516 int steps;
02517 double dsteps;
02518 unsigned char smByte = 0;
02519
02520 for (;;)
02521 {
02522 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
02523 {
02524 if (smClkPhase[axis])
02525 {
02526
02527 smByte &= ~(0x02 << (axis << 1));
02528
02529 smClkPhase[axis] = 0;
02530 }
02531 else
02532 {
02533
02534
02535 fpInUse = 1;
02536 dsteps = jointPos[axis] * smStepsPerUnit[axis] +
02537 emcmotStatus->inputOffset[axis];
02538 if (dsteps < 0.0)
02539 steps = (int) (dsteps - 0.5);
02540 else
02541 steps = (int) (dsteps + 0.5);
02542 fpInUse = 0;
02543 if (steps > smStepsAccum[axis])
02544 {
02545 smStepsAccum[axis]++;
02546 smByte |= (0x01 << (axis << 1));
02547 smByte |= (0x02 << (axis << 1));
02548
02549 smClkPhase[axis] = 1;
02550 }
02551 else if (steps < smStepsAccum[axis])
02552 {
02553 smStepsAccum[axis]--;
02554 smByte &= ~(0x01 << (axis << 1));
02555 smByte |= (0x02 << (axis << 1));
02556
02557 smClkPhase[axis] = 1;
02558 }
02559 }
02560 }
02561
02562 pptDioByteWrite(0, smByte);
02563
02564 rt_task_wait();
02565 }
02566 }
02567
02568 #endif
02569
02570 int init_module(void)
02571 {
02572 int axis;
02573 int t;
02574 #ifdef rtlinux
02575 RTIME now;
02576 #endif
02577 PID_STRUCT pid;
02578
02579 #ifdef rtlinux
02580
02581 #ifdef RT_FIFO
02582 rtf_create(EMCMOT_COMMAND_RTF, sizeof(EMCMOT_COMMAND) + 1);
02583 rtf_create(EMCMOT_STATUS_RTF, sizeof(EMCMOT_STATUS) + 1);
02584 rtf_create(EMCMOT_ERROR_RTF, EMCMOT_ERROR_NUM * EMCMOT_ERROR_LEN + 1);
02585
02586
02587
02588 emcmotCommand = &emcmotCommandBuffer;
02589 emcmotStatus = &emcmotStatusBuffer;
02590
02591 #else
02592
02593 emcmotStruct = (EMCMOT_STRUCT *) SHMEM_BASE_ADDRESS;
02594
02595 #endif
02596
02597 #else
02598
02599 shmem = rcs_shm_open(SHMEM_KEY, sizeof(EMCMOT_STRUCT), 1, 0666);
02600 if (NULL == shmem ||
02601 NULL == shmem->addr)
02602 {
02603 diagnostics("can't get shared memory\n");
02604 return -1;
02605 }
02606
02607 memset(shmem->addr, 0, sizeof(EMCMOT_STRUCT));
02608
02609 emcmotStruct = (EMCMOT_STRUCT *) shmem->addr;
02610
02611 #endif
02612
02613 #ifndef RT_FIFO
02614
02615 emcmotCommand = (EMCMOT_COMMAND *) &emcmotStruct->command;
02616 emcmotStatus = (EMCMOT_STATUS *) &emcmotStruct->status;
02617 emcmotError = (EMCMOT_ERROR *) &emcmotStruct->error;
02618 emcmotLog = (EMCMOT_LOG *) &emcmotStruct->log;
02619
02620
02621 for (t = 0; t < sizeof(EMCMOT_STRUCT); t++)
02622 {
02623 ((char *) emcmotStruct)[t] = 0;
02624 }
02625 #endif
02626
02627
02628 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
02629 {
02630 maxLimitSwitchCount[axis] = 0;
02631 minLimitSwitchCount[axis] = 0;
02632
02633 smStepsPerUnit[axis] = 1.0;
02634 smStepsAccum[axis] = 0;
02635 smClkPhase[axis] = 0;
02636
02637 }
02638
02639 #ifndef RT_FIFO
02640
02641 emcmotErrorInit(emcmotError);
02642 #endif
02643
02644
02645 emcmotCommand->head = 0;
02646 emcmotCommand->command = 0;
02647 emcmotCommand->commandNum = 0;
02648 emcmotCommand->tail = 0;
02649
02650
02651
02652 emcmotStatus->head = 0;
02653
02654 emcmotStatus->motionFlag = 0;
02655 SET_MOTION_ERROR_FLAG(0);
02656 SET_MOTION_COORD_FLAG(0);
02657 emcmotStatus->split = 0;
02658 emcmotStatus->commandEcho = 0;
02659 emcmotStatus->commandNumEcho = 0;
02660 emcmotStatus->commandStatus = 0;
02661 emcmotStatus->heartbeat = 0;
02662 emcmotStatus->computeTime = 0.0;
02663 emcmotStatus->numAxes = EMCMOT_MAX_AXIS;
02664 emcmotStatus->trajCycleTime = TRAJ_CYCLE_TIME;
02665 emcmotStatus->servoCycleTime = SERVO_CYCLE_TIME;
02666 emcmotStatus->pos.tran.x = 0.0;
02667 emcmotStatus->pos.tran.y = 0.0;
02668 emcmotStatus->pos.tran.z = 0.0;
02669 emcmotStatus->actualPos.tran.x = 0.0;
02670 emcmotStatus->actualPos.tran.y = 0.0;
02671 emcmotStatus->actualPos.tran.z = 0.0;
02672 emcmotStatus->vel = VELOCITY;
02673 emcmotStatus->limitVel = VELOCITY;
02674 emcmotStatus->acc = ACCELERATION;
02675 emcmotStatus->qVscale = 1.0;
02676 emcmotStatus->id = 0;
02677 emcmotStatus->depth = 0;
02678 emcmotStatus->activeDepth = 0;
02679 emcmotStatus->paused = 0;
02680 SET_MOTION_INPOS_FLAG(1);
02681 emcmotStatus->logOpen = 0;
02682 emcmotStatus->logStarted = 0;
02683 emcmotStatus->logSize = 0;
02684 emcmotStatus->logSkip = 0;
02685 emcmotStatus->logPoints = 0;
02686 SET_MOTION_ENABLE_FLAG(0);
02687
02688 oldPos = emcmotStatus->pos;
02689 oldVel.tran.x = 0.0;
02690 oldVel.tran.y = 0.0;
02691 oldVel.tran.z = 0.0;
02692
02693 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
02694 {
02695 emcmotStatus->homingVel[axis] = VELOCITY;
02696 emcmotStatus->axisFlag[axis] = 0;
02697 emcmotStatus->maxLimit[axis] = MAX_LIMIT;
02698 emcmotStatus->minLimit[axis] = MIN_LIMIT;
02699 emcmotStatus->maxOutput[axis] = MAX_OUTPUT;
02700 emcmotStatus->minOutput[axis] = MIN_OUTPUT;
02701 emcmotStatus->maxFerror[axis] = MAX_FERROR;
02702 emcmotStatus->ferror[axis] = 0.0;
02703 emcmotStatus->outputScale[axis] = OUTPUT_SCALE;
02704 emcmotStatus->outputOffset[axis] = OUTPUT_OFFSET;
02705 emcmotStatus->inputScale[axis] = INPUT_SCALE;
02706 emcmotStatus->inputOffset[axis] = INPUT_OFFSET;
02707 emcmotStatus->axVscale[axis] = 1.0;
02708 SET_AXIS_ENABLE_FLAG(axis, 0);
02709 SET_AXIS_ACTIVE_FLAG(axis, 1);
02710 SET_AXIS_NSL_FLAG(axis, 0);
02711 SET_AXIS_PSL_FLAG(axis, 0);
02712 SET_AXIS_NHL_FLAG(axis, 0);
02713 SET_AXIS_PHL_FLAG(axis, 0);
02714 SET_AXIS_INPOS_FLAG(axis, 1);
02715 SET_AXIS_HOMING_FLAG(axis, 0);
02716 SET_AXIS_HOMED_FLAG(axis, 0);
02717 SET_AXIS_FERROR_FLAG(axis, 0);
02718 SET_AXIS_FAULT_FLAG(axis, 0);
02719 SET_AXIS_ERROR_FLAG(axis, 0);
02720 emcmotStatus->axisPolarity[axis] = (EMCMOT_AXIS_FLAG) 0xFFFFFFFF;
02721
02722 }
02723
02724
02725
02726
02727 mmxavgInit(&tMmxavg, tMmxavgSpace, MMXAVG_SIZE);
02728 mmxavgInit(&sMmxavg, sMmxavgSpace, MMXAVG_SIZE);
02729 mmxavgInit(&nMmxavg, nMmxavgSpace, MMXAVG_SIZE);
02730 emcmotStatus->tMin = 0.0;
02731 emcmotStatus->tMax = 0.0;
02732 emcmotStatus->tAvg = 0.0;
02733 emcmotStatus->sMin = 0.0;
02734 emcmotStatus->sMax = 0.0;
02735 emcmotStatus->sAvg = 0.0;
02736 emcmotStatus->nMin = 0.0;
02737 emcmotStatus->nMax = 0.0;
02738 emcmotStatus->nAvg = 0.0;
02739
02740
02741 #ifdef rtlinux
02742 if ( -1 == sqInitQueue(&queue,(SEGMENT *)(SHMEM_BASE_ADDRESS+sizeof(EMCMOT_STRUCT)), TC_QUEUE_SIZE))
02743 #else
02744 sqMemPool = (SEGMENT *)malloc(TC_QUEUE_SIZE*sizeof(SEGMENT));
02745 if ( sqMemPool == NULL )
02746 {
02747 diagnostics("Error in init_module(): cannot allocate memory for segmentqueue\n");
02748 return -1;
02749 }
02750 if ( -1 == sqInitQueue(&queue,sqMemPool, TC_QUEUE_SIZE))
02751 #endif
02752 {
02753 diagnostics("can't initialize motion queue\n");
02754 return -1;
02755 }
02756 sqSetCycleTime(&queue, emcmotStatus->trajCycleTime);
02757 sqSetPos(&queue, emcmotStatus->pos);
02758 sqSetVmax(&queue, emcmotStatus->vel);
02759 sqSetFeed(&queue, emcmotStatus->vel);
02760
02761
02762
02763 sqSetMaxAcc(&queue, emcmotStatus->acc);
02764 sqSetMaxFeedOverride(&queue, 1.0 );
02765
02766
02767 pid.p = P_GAIN;
02768 pid.i = I_GAIN;
02769 pid.d = D_GAIN;
02770 pid.ff0 = FF0_GAIN;
02771 pid.ff1 = FF1_GAIN;
02772 pid.ff2 = FF2_GAIN;
02773 pid.backlash = BACKLASH;
02774 pid.bias = BIAS;
02775 pid.maxError = MAX_ERROR;
02776
02777 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
02778 {
02779 if (-1 == tpCreate(&freeAxis[axis], FREE_AXIS_QUEUE_SIZE, freeAxisTcSpace[axis]))
02780 {
02781 diagnostics("can't create axis queue %d\n", axis);
02782 return -1;
02783 }
02784 tpInit(&freeAxis[axis]);
02785 tpSetCycleTime(&freeAxis[axis], emcmotStatus->trajCycleTime);
02786 tpSetPos(&freeAxis[axis], emcmotStatus->pos);
02787 tpSetVmax(&freeAxis[axis], emcmotStatus->vel);
02788 tpSetAmax(&freeAxis[axis], emcmotStatus->acc);
02789 pidInit(&emcmotStatus->pid[axis]);
02790 pidSetGains(&emcmotStatus->pid[axis], pid);
02791 cubicInit(&cubic[axis]);
02792 }
02793
02794
02795
02796 setTrajCycleTime(TRAJ_CYCLE_TIME);
02797 setServoCycleTime(SERVO_CYCLE_TIME);
02798
02799
02800 if (-1 == extMotInit((const char *) 0))
02801 {
02802 diagnostics("can't initialize motion hardware\n");
02803 return -1;
02804 }
02805 if (-1 == extDioInit((const char *) 0))
02806 {
02807 diagnostics("can't initialize DIO hardware\n");
02808 return -1;
02809 }
02810 if (-1 == extAioInit((const char *) 0))
02811 {
02812 diagnostics("can't initialize AIO hardware\n");
02813 return -1;
02814 }
02815
02816 extEncoderSetIndexModel(EXT_ENCODER_INDEX_MODEL_MANUAL);
02817 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
02818 {
02819 rawInput[axis] = 0.0;
02820 rawOutput[axis] = 0.0;
02821 trajPos[axis] = 0.0;
02822 jointPos[axis] = 0.0;
02823 oldJointPos[axis] = 0.0;
02824 oldInput[axis] = 0.0;
02825
02826 waitingForLatch[axis] = 0;
02827 latchFlag[axis] = 0;
02828 saveLatch[axis] = 0.0;
02829
02830 wasOnLimit[axis] = 0;
02831 emcmotStatus->input[axis] = 0.0;
02832 lastInput[axis] = 0.0;
02833 emcmotStatus->output[axis] = 0.0;
02834
02835 extAmpEnable(axis,
02836 ! GET_AXIS_ENABLE_POLARITY(axis));
02837 }
02838
02839 emcmotStatus->tail = 0;
02840
02841 #ifdef rtlinux
02842
02843
02844 now = rt_get_time();
02845
02846
02847 rt_task_init(&emcmotTask,
02848 emcmotController,
02849 0,
02850 RT_TASK_STACK_SIZE,
02851 RT_TASK_PRIORITY);
02852
02853
02854
02855 #if defined(rtlinux_09J) || defined(rtlinux_1_0)
02856 rt_task_use_fp(&emcmotTask, 1);
02857 #else
02858 rt_use_fp(1);
02859 #endif
02860
02861
02862 rt_task_make_periodic(&emcmotTask,
02863 now + SECS_TO_RTIME(0.010),
02864 (RTIME) (RT_TICKS_PER_SEC *
02865 emcmotStatus->servoCycleTime));
02866
02867 #ifdef STEPPER_MOTORS
02868
02869
02870 rt_task_init(&smTask,
02871 smController,
02872 0,
02873 SM_TASK_STACK_SIZE,
02874 SM_TASK_PRIORITY);
02875
02876
02877 #if defined(rtlinux_09J) || defined(rtlinux_1_0)
02878 rt_task_use_fp(&smTask, 1);
02879 #endif
02880
02881
02882 rt_task_make_periodic(&smTask,
02883 now + SECS_TO_RTIME(0.010),
02884 ((RTIME) (RT_TICKS_PER_SEC *
02885 emcmotStatus->servoCycleTime)) >> 1);
02886
02887 #endif
02888
02889
02890 diagnostics("inited emcmot\n");
02891
02892 #endif
02893
02894 #if defined (rtlinux) && defined (RT_FIFO)
02895
02896 rtf_create_handler(EMCMOT_COMMAND_RTF,
02897 emcmotCommandHandler
02898 );
02899
02900 #endif
02901 return 0;
02902 }
02903
02904 void cleanup_module(void)
02905 {
02906 int axis;
02907
02908
02909 #if !defined(rtlinux)
02910 free(sqMemPool);
02911 #endif
02912 sqTrashQueue(&queue);
02913
02914
02915 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
02916 {
02917 tpDelete(&freeAxis[axis]);
02918 }
02919
02920
02921 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
02922 {
02923 extAmpEnable(axis,
02924 ! GET_AXIS_ENABLE_POLARITY(axis));
02925 }
02926
02927
02928 extAioQuit();
02929 extDioQuit();
02930 extMotQuit();
02931
02932 #ifdef rtlinux
02933
02934 #ifdef RT_FIFO
02935 rtf_destroy(EMCMOT_COMMAND_RTF);
02936 rtf_destroy(EMCMOT_STATUS_RTF);
02937 rtf_destroy(EMCMOT_ERROR_RTF);
02938 #endif
02939
02940
02941 rt_task_delete(&emcmotTask);
02942
02943
02944 diagnostics("exited emcmot\n");
02945
02946 #ifdef STEPPER_MOTORS
02947
02948
02949 rt_task_delete(&smTask);
02950
02951 #endif
02952
02953 #else
02954
02955
02956 if (NULL != shmem)
02957 {
02958 rcs_shm_close(shmem);
02959 shmem = NULL;
02960 }
02961
02962 #endif
02963 }
02964
02965 #ifndef EMCMOT_NO_MAIN
02966
02967 static int done = 0;
02968 static void quit(int sig)
02969 {
02970 done = 1;
02971 }
02972
02973 #include <string.h>
02974 #include <signal.h>
02975
02976 static int getArgs(int argc, char *argv[])
02977 {
02978 int t;
02979 int len;
02980
02981 for (t = 1; t < argc; t++)
02982 {
02983
02984
02985
02986
02987 if (!strcmp(argv[t], "-ini"))
02988 {
02989 if (t == argc - 1)
02990 {
02991 diagnostics("missing -ini parameter\n");
02992 return -1;
02993 }
02994 else
02995 {
02996 strcpy(EMCMOT_INIFILE, argv[t+1]);
02997 t++;
02998 continue;
02999 }
03000 }
03001
03002
03003 len = strlen("SHMEM_BASE_ADDRESS");
03004 if (! strncmp(argv[t], "SHMEM_BASE_ADDRESS", len))
03005 {
03006 if (argv[t][len] != '=' ||
03007 1 != sscanf(&argv[t][len + 1], "%i", &SHMEM_BASE_ADDRESS))
03008 {
03009 diagnostics("syntax: %s SHMEM_BASE_ADDRESS=integer\n", argv[0]);
03010 return -1;
03011 }
03012 else
03013 {
03014 continue;
03015 }
03016 }
03017
03018
03019 len = strlen("SHMEM_KEY");
03020 if (! strncmp(argv[t], "SHMEM_KEY", len))
03021 {
03022 if (argv[t][len] != '=' ||
03023 1 != sscanf(&argv[t][len + 1], "%i", &SHMEM_KEY))
03024 {
03025 diagnostics("syntax: %s SHMEM_KEY=integer\n", argv[0]);
03026 return -1;
03027 }
03028 else
03029 {
03030 continue;
03031 }
03032 }
03033
03034
03035 diagnostics("bad argument to %s: %s\n", argv[0], argv[t]);
03036 return -1;
03037 }
03038
03039 return 0;
03040 }
03041
03042
03043
03044
03045
03046
03047 int main(int argc, char *argv[])
03048 {
03049 int t;
03050 int shm;
03051 int base;
03052 double delta;
03053
03054
03055 signal(SIGINT, quit);
03056
03057
03058 if (0 != getArgs(argc, argv))
03059 {
03060 diagnostics("can't init module-- bad arguments\n");
03061 exit(1);
03062 }
03063
03064
03065 if (-1 == init_module())
03066 {
03067 diagnostics("can't init module-- execution permission problems?\n");
03068 exit(1);
03069 }
03070
03071 while (! done)
03072 {
03073 delta = etime();
03074 emcmotController(0);
03075 delta = etime() - delta;
03076 delta = emcmotStatus->servoCycleTime - delta;
03077
03078 if (delta > 0.0)
03079 {
03080 esleep(delta);
03081 }
03082 }
03083
03084 cleanup_module();
03085 exit(0);
03086 }
03087
03088 #endif