00001 #ifdef rtlinux
00002 #ifndef MODULE
00003 #define MODULE
00004 #endif
00005 #endif
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
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
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
00278 #ifdef rtlinux
00279
00280 #if (defined(rtlinux2) || defined(RTLINUX_V2)) && !defined(CONFIG_RTL_USE_V1_API)
00281 #define USE_RTL2
00282 #endif
00283
00284
00285 #ifdef USE_RTL2
00286 #include <rtl.h>
00287 #ifdef RT_FIFO
00288 #include <rtl_fifo.h>
00289 #endif
00290 #include <time.h>
00291 #include <rtl_sched.h>
00292 #include <rtl_sync.h>
00293 #include <pthread.h>
00294 #include <unistd.h>
00295 #include <rtl_debug.h>
00296 #include <errno.h>
00297 #include "mbuff.h"
00298 #endif
00299
00300
00301
00302
00303
00304 #include <linux/module.h>
00305 #include <linux/kernel.h>
00306 #include <linux/version.h>
00307 #include <linux/errno.h>
00308 #include <linux/mm.h>
00309
00310 #ifndef USE_RTL2
00311 #include <rtl_sched.h>
00312 #include <rtl_fifo.h>
00313 #endif
00314
00315
00316 #include <asm/io.h>
00317
00318 #include <math.h>
00319 #include <stdarg.h>
00320
00321 #else
00322
00323 #include "_timer.h"
00324 #include "_shm.h"
00325 #if !defined(UNDER_CE) && !defined(NO_STDIO_SUPPORT)
00326 #include <stdio.h>
00327 #endif
00328 #include <stdlib.h>
00329 #include <math.h>
00330 #include <stdarg.h>
00331 #include <string.h>
00332
00333 #endif
00334
00335 #include "posemath.h"
00336 #include "emcpos.h"
00337 #include "emcmotcfg.h"
00338 #include "emcmotglb.h"
00339 #include "emcmot.h"
00340 #include "pid.h"
00341 #include "cubic.h"
00342 #include "tc.h"
00343 #include "tp.h"
00344 #include "extintf.h"
00345 #include "mmxavg.h"
00346 #include "emcmotlog.h"
00347
00348
00349 #ifndef __GNUC__
00350 #ifndef __attribute__
00351 #define __attribute__(x)
00352 #endif
00353 #endif
00354
00355 static char __attribute__((unused)) ident[] = "$Id: emcstepmot.c,v 1.18 2001/10/18 15:29:09 wshackle Exp $";
00356
00357 void extMotDout(unsigned char byte)
00358 {
00359 return;
00360 }
00361
00362 #ifdef rtlinux
00363
00364
00365
00366 #define SECS_TO_RTIME(secs) ((RTIME) (RT_TICKS_PER_SEC * secs))
00367
00368
00369 #ifdef USE_RTL2
00370 static pthread_t emcmotTask;
00371 #else
00372 static RT_TASK emcmotTask;
00373 #endif
00374
00375 #define RT_TASK_PRIORITY 2
00376
00377 #define RT_TASK_STACK_SIZE 8192
00378
00379 #ifdef STEPPER_MOTORS
00380 #ifdef USE_RTL2
00381 static pthread_t smTask;
00382 #else
00383 static RT_TASK smTask;
00384 #endif
00385 #define SM_TASK_PRIORITY 1
00386 #define SM_TASK_STACK_SIZE 4096
00387 #endif
00388
00389
00390 #define SOUND_PORT 0x61
00391 #define SOUND_MASK 0x02
00392 static unsigned char soundByte;
00393
00394 #endif
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 #if defined (rtlinux) && defined (RT_FIFO)
00421
00422
00423 static EMCMOT_COMMAND emcmotCommandBuffer;
00424 static EMCMOT_STATUS emcmotStatusBuffer;
00425 static EMCMOT_CONFIG emcmotConfigBuffer;
00426 static EMCMOT_DEBUG emcmotDebugBuffer;
00427
00428 #else
00429
00430
00431 EMCMOT_STRUCT *emcmotStruct;
00432
00433 #ifndef rtlinux
00434
00435 static shm_t *shmem = NULL;
00436 #endif
00437
00438 #endif
00439
00440
00441
00442 static EMCMOT_COMMAND *emcmotCommand;
00443 static EMCMOT_STATUS *emcmotStatus;
00444 static EMCMOT_CONFIG *emcmotConfig;
00445 static EMCMOT_DEBUG *emcmotDebug;
00446
00447 #if defined (rtlinux) && defined (RT_FIFO)
00448 #else
00449 static EMCMOT_ERROR *emcmotError;
00450 static EMCMOT_LOG *emcmotLog;
00451 static EMCMOT_COMP *emcmotComp[EMCMOT_MAX_AXIS];
00452 #endif
00453
00454 static EMCMOT_LOG_STRUCT ls;
00455 static int logSkip = 0;
00456 static int loggingAxis = 0;
00457 static int logIt = 0;
00458
00459
00460 static int wdEnabling = 0;
00461 static int wdEnabled = 0;
00462 static int wdWait = 0;
00463 static int wdCount = 0;
00464 static unsigned char wdToggle = 0;
00465
00466
00467 static unsigned char allHomed = 0;
00468
00469
00470 static double jointHome[EMCMOT_MAX_AXIS];
00471
00472
00473 static EmcPose worldHome = {{0.0, 0.0, 0.0},
00474 0.0, 0.0, 0.0};
00475
00476
00477 static KINEMATICS_FORWARD_FLAGS fflags = 0;
00478 static KINEMATICS_INVERSE_FLAGS iflags = 0;
00479
00480
00481 static int kinType = 0;
00482
00483
00484 #define LIMIT_SWITCH_DEBOUNCE 10
00485 static int maxLimitSwitchCount[EMCMOT_MAX_AXIS];
00486 static int minLimitSwitchCount[EMCMOT_MAX_AXIS];
00487 #define AMP_FAULT_DEBOUNCE 100
00488 static int ampFaultCount[EMCMOT_MAX_AXIS];
00489
00490
00491 #ifdef rtlinux
00492 #define diagnostics printk
00493 #else
00494 #ifdef UNDER_CE
00495 #include "rcs_prnt.hh"
00496 #define diagnostics rcs_print
00497 #else
00498 #define diagnostics printf
00499 #endif
00500 #endif
00501
00502 static inline void MARK_EMCMOT_CONFIG_CHANGE(void)
00503 {
00504 if(emcmotConfig->head == emcmotConfig->tail) {
00505 emcmotConfig->config_num++;
00506 emcmotStatus->config_num = emcmotConfig->config_num;
00507 emcmotConfig->head++;
00508 }
00509 }
00510
00511
00512
00513
00514
00515 #define GET_MOTION_ERROR_FLAG() (emcmotStatus->motionFlag & EMCMOT_MOTION_ERROR_BIT ? 1 : 0)
00516
00517 #define SET_MOTION_ERROR_FLAG(fl) if (fl) emcmotStatus->motionFlag |= EMCMOT_MOTION_ERROR_BIT; else emcmotStatus->motionFlag &= ~EMCMOT_MOTION_ERROR_BIT;
00518
00519 #define GET_MOTION_COORD_FLAG() (emcmotStatus->motionFlag & EMCMOT_MOTION_COORD_BIT ? 1 : 0)
00520
00521 #define SET_MOTION_COORD_FLAG(fl) if (fl) emcmotStatus->motionFlag |= EMCMOT_MOTION_COORD_BIT; else emcmotStatus->motionFlag &= ~EMCMOT_MOTION_COORD_BIT;
00522
00523 #define GET_MOTION_INPOS_FLAG() (emcmotStatus->motionFlag & EMCMOT_MOTION_INPOS_BIT ? 1 : 0)
00524
00525 #define SET_MOTION_INPOS_FLAG(fl) if (fl) emcmotStatus->motionFlag |= EMCMOT_MOTION_INPOS_BIT; else emcmotStatus->motionFlag &= ~EMCMOT_MOTION_INPOS_BIT;
00526
00527 #define GET_MOTION_ENABLE_FLAG() (emcmotStatus->motionFlag & EMCMOT_MOTION_ENABLE_BIT ? 1 : 0)
00528
00529 #define SET_MOTION_ENABLE_FLAG(fl) if (fl) emcmotStatus->motionFlag |= EMCMOT_MOTION_ENABLE_BIT; else emcmotStatus->motionFlag &= ~EMCMOT_MOTION_ENABLE_BIT;
00530
00531
00532
00533 #define GET_AXIS_ENABLE_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_ENABLE_BIT ? 1 : 0)
00534
00535 #define SET_AXIS_ENABLE_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_ENABLE_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_ENABLE_BIT;
00536
00537 #define GET_AXIS_ACTIVE_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_ACTIVE_BIT ? 1 : 0)
00538
00539 #define SET_AXIS_ACTIVE_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_ACTIVE_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_ACTIVE_BIT;
00540
00541 #define GET_AXIS_INPOS_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_INPOS_BIT ? 1 : 0)
00542
00543 #define SET_AXIS_INPOS_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_INPOS_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_INPOS_BIT;
00544
00545 #define GET_AXIS_ERROR_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_ERROR_BIT ? 1 : 0)
00546
00547 #define SET_AXIS_ERROR_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_ERROR_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_ERROR_BIT;
00548
00549 #define GET_AXIS_PSL_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_MAX_SOFT_LIMIT_BIT ? 1 : 0)
00550
00551 #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;
00552
00553 #define GET_AXIS_NSL_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_MIN_SOFT_LIMIT_BIT ? 1 : 0)
00554
00555 #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;
00556
00557 #define GET_AXIS_PHL_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_MAX_HARD_LIMIT_BIT ? 1 : 0)
00558
00559 #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;
00560
00561 #define GET_AXIS_NHL_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_MIN_HARD_LIMIT_BIT ? 1 : 0)
00562
00563 #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;
00564
00565 #define GET_AXIS_HOME_SWITCH_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_HOME_SWITCH_BIT ? 1 : 0)
00566
00567 #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;
00568
00569 #define GET_AXIS_HOMING_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_HOMING_BIT ? 1 : 0)
00570
00571 #define SET_AXIS_HOMING_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_HOMING_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_HOMING_BIT;
00572
00573 #define GET_AXIS_HOMED_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_HOMED_BIT ? 1 : 0)
00574
00575 #define SET_AXIS_HOMED_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_HOMED_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_HOMED_BIT;
00576
00577 #define GET_AXIS_FERROR_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_FERROR_BIT ? 1 : 0)
00578
00579 #define SET_AXIS_FERROR_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_FERROR_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_FERROR_BIT;
00580
00581 #define GET_AXIS_FAULT_FLAG(ax) (emcmotStatus->axisFlag[ax] & EMCMOT_AXIS_FAULT_BIT ? 1 : 0)
00582
00583 #define SET_AXIS_FAULT_FLAG(ax,fl) if (fl) emcmotStatus->axisFlag[ax] |= EMCMOT_AXIS_FAULT_BIT; else emcmotStatus->axisFlag[ax] &= ~EMCMOT_AXIS_FAULT_BIT;
00584
00585
00586
00587 #define GET_AXIS_ENABLE_POLARITY(ax) (emcmotConfig->axisPolarity[ax] & EMCMOT_AXIS_ENABLE_BIT ? 1 : 0)
00588
00589 #define SET_AXIS_ENABLE_POLARITY(ax,fl) if (fl) emcmotConfig->axisPolarity[ax] |= EMCMOT_AXIS_ENABLE_BIT; else emcmotConfig->axisPolarity[ax] &= ~EMCMOT_AXIS_ENABLE_BIT;
00590
00591 #define GET_AXIS_PHL_POLARITY(ax) (emcmotConfig->axisPolarity[ax] & EMCMOT_AXIS_MAX_HARD_LIMIT_BIT ? 1 : 0)
00592
00593 #define SET_AXIS_PHL_POLARITY(ax,fl) if (fl) emcmotConfig->axisPolarity[ax] |= EMCMOT_AXIS_MAX_HARD_LIMIT_BIT; else emcmotConfig->axisPolarity[ax] &= ~EMCMOT_AXIS_MAX_HARD_LIMIT_BIT;
00594
00595 #define GET_AXIS_NHL_POLARITY(ax) (emcmotConfig->axisPolarity[ax] & EMCMOT_AXIS_MIN_HARD_LIMIT_BIT ? 1 : 0)
00596
00597 #define SET_AXIS_NHL_POLARITY(ax,fl) if (fl) emcmotConfig->axisPolarity[ax] |= EMCMOT_AXIS_MIN_HARD_LIMIT_BIT; else emcmotConfig->axisPolarity[ax] &= ~EMCMOT_AXIS_MIN_HARD_LIMIT_BIT;
00598
00599 #define GET_AXIS_HOME_SWITCH_POLARITY(ax) (emcmotConfig->axisPolarity[ax] & EMCMOT_AXIS_HOME_SWITCH_BIT ? 1 : 0)
00600
00601 #define SET_AXIS_HOME_SWITCH_POLARITY(ax,fl) if (fl) emcmotConfig->axisPolarity[ax] |= EMCMOT_AXIS_HOME_SWITCH_BIT; else emcmotConfig->axisPolarity[ax] &= ~EMCMOT_AXIS_HOME_SWITCH_BIT;
00602
00603 #define GET_AXIS_HOMING_POLARITY(ax) (emcmotConfig->axisPolarity[ax] & EMCMOT_AXIS_HOMING_BIT ? 1 : 0)
00604
00605 #define SET_AXIS_HOMING_POLARITY(ax,fl) if (fl) emcmotConfig->axisPolarity[ax] |= EMCMOT_AXIS_HOMING_BIT; else emcmotConfig->axisPolarity[ax] &= ~EMCMOT_AXIS_HOMING_BIT;
00606
00607 #define GET_AXIS_FAULT_POLARITY(ax) (emcmotConfig->axisPolarity[ax] & EMCMOT_AXIS_FAULT_BIT ? 1 : 0)
00608
00609 #define SET_AXIS_FAULT_POLARITY(ax,fl) if (fl) emcmotConfig->axisPolarity[ax] |= EMCMOT_AXIS_FAULT_BIT; else emcmotConfig->axisPolarity[ax] &= ~EMCMOT_AXIS_FAULT_BIT;
00610
00611 static TP_STRUCT queue;
00612
00613
00614
00615
00616 static TP_STRUCT freeAxis[EMCMOT_MAX_AXIS];
00617
00618
00619
00620 static EmcPose freePose = {{0.0, 0.0, 0.0}, 0.0, 0.0, 0.0};
00621 static CUBIC_STRUCT cubic[EMCMOT_MAX_AXIS];
00622
00623
00624
00625 static TC_STRUCT queueTcSpace[DEFAULT_TC_QUEUE_SIZE + 10];
00626 #define FREE_AXIS_QUEUE_SIZE 4
00627 static TC_STRUCT freeAxisTcSpace[EMCMOT_MAX_AXIS][FREE_AXIS_QUEUE_SIZE];
00628
00629 static double rawInput[EMCMOT_MAX_AXIS];
00630 static double rawOutput[EMCMOT_MAX_AXIS];
00631
00632 static double coarseJointPos[EMCMOT_MAX_AXIS];
00633 static double jointPos[EMCMOT_MAX_AXIS];
00634 static double jointVel[EMCMOT_MAX_AXIS];
00635 static double oldJointPos[EMCMOT_MAX_AXIS];
00636 static double oldInput[EMCMOT_MAX_AXIS];
00637
00638
00639 static double inverseInputScale[EMCMOT_MAX_AXIS];
00640 static double inverseOutputScale[EMCMOT_MAX_AXIS];
00641 static EmcPose oldPos;
00642 static EmcPose oldVel, newVel;
00643 static EmcPose newAcc;
00644
00645
00646 static double bigVel = 1.0;
00647
00648 static int waitingForLatch[EMCMOT_MAX_AXIS];
00649 static int latchFlag[EMCMOT_MAX_AXIS];
00650 static double saveLatch[EMCMOT_MAX_AXIS];
00651
00652 static int enabling = 0;
00653 static int coordinating = 0;
00654
00655 static int wasOnLimit = 0;
00656
00657
00658
00659
00660 static int onLimit = 0;
00661
00662
00663 static int overriding = 0;
00664
00665
00666 static int stepping = 0;
00667 static int idForStep = 0;
00668
00669 #ifdef STEPPER_MOTORS
00670
00671
00672 #include "parport.h"
00673
00674 static char smInhibit = 0 ;
00675 static int smSteps[EMCMOT_MAX_AXIS];
00676 static double smStepsPerUnit[EMCMOT_MAX_AXIS];
00677 static double smMagUnitsPerStep[EMCMOT_MAX_AXIS];
00678 static double smMaxStepsPerUnit;
00679
00680 static double smVPmax;
00681 static double smCycleTime;
00682 static int smCyclesPerAxis = 1;
00683 static int smNewCycle[EMCMOT_MAX_AXIS];
00684
00685 #endif
00686
00687
00688 #if 0
00689 static MMXAVG_STRUCT tMmxavg;
00690 static MMXAVG_STRUCT sMmxavg;
00691 static MMXAVG_STRUCT nMmxavg;
00692 #endif
00693
00694 #ifdef rtlinux
00695
00696 static double etime(void)
00697 {
00698 #ifdef USE_RTL2
00699 hrtime_t now;
00700
00701 now = gethrtime();
00702
00703 return ((double) now) / ((double) HRTICKS_PER_SEC);
00704 #else
00705
00706 RTIME now;
00707
00708 now = rt_get_time();
00709
00710 return ((double) now) / ((double) RT_TICKS_PER_SEC);
00711 #endif
00712 }
00713
00714 #endif
00715
00716 #ifdef UNDER_CE
00717 #include "rcs_ce.h"
00718 #endif
00719
00720 static void reportError(const char *fmt, ...)
00721 {
00722 va_list args;
00723 char error[EMCMOT_ERROR_LEN];
00724
00725 va_start(args, fmt);
00726 #ifndef UNDER_CE
00727 vsprintf(error, fmt, args);
00728 #else
00729 RCS_CE_VSPRINTF(error,fmt,args);
00730 #endif
00731 va_end(args);
00732
00733 #if defined (rtlinux) && defined (RT_FIFO)
00734 rtf_put(EMCMOT_ERROR_RTF, error, EMCMOT_ERROR_LEN);
00735
00736 #else
00737 emcmotErrorPut(emcmotError, error);
00738
00739 #endif
00740 }
00741
00742
00743 static int isHoming(void)
00744 {
00745 int axis;
00746
00747 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
00748 if (GET_AXIS_HOMING_FLAG(axis)) {
00749 return 1;
00750 }
00751 }
00752
00753
00754 return 0;
00755 }
00756
00757
00758 #define AXRANGE(axis) ((emcmotConfig->maxLimit[axis] - emcmotConfig->minLimit[axis]))
00759
00760
00761
00762 static int inRange(EmcPose pos)
00763 {
00764 double joint[EMCMOT_MAX_AXIS];
00765 int axis;
00766
00767
00768 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
00769 joint[axis] = 0.0;
00770 }
00771
00772
00773 kinematicsInverse(&pos, joint, &iflags, &fflags);
00774
00775 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
00776 if (! GET_AXIS_ACTIVE_FLAG(axis)) {
00777
00778 continue;
00779 }
00780
00781 if (joint[axis] > emcmotConfig->maxLimit[axis] ||
00782 joint[axis] < emcmotConfig->minLimit[axis]) {
00783 return 0;
00784 }
00785 }
00786
00787
00788 return 1;
00789 }
00790
00791
00792
00793 static int checkLimits(void)
00794 {
00795 int axis;
00796
00797 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
00798 if (! GET_AXIS_ACTIVE_FLAG(axis)) {
00799
00800 continue;
00801 }
00802
00803 if (GET_AXIS_PSL_FLAG(axis) ||
00804 GET_AXIS_NSL_FLAG(axis) ||
00805 GET_AXIS_PHL_FLAG(axis) ||
00806 GET_AXIS_NHL_FLAG(axis)) {
00807 return 0;
00808 }
00809 }
00810
00811 return 1;
00812 }
00813
00814
00815
00816
00817
00818 static int checkJog(int axis, double vel)
00819 {
00820 if (emcmotStatus->overrideLimits) {
00821 return 1;
00822 }
00823
00824 if (axis < 0 ||
00825 axis >= EMCMOT_MAX_AXIS) {
00826 return 0;
00827 }
00828
00829 if (vel > 0.0 &&
00830 (GET_AXIS_PSL_FLAG(axis) ||
00831 GET_AXIS_PHL_FLAG(axis))) {
00832 return 0;
00833 }
00834
00835 if (vel < 0.0 &&
00836 (GET_AXIS_NSL_FLAG(axis) ||
00837 GET_AXIS_NHL_FLAG(axis))) {
00838 return 0;
00839 }
00840
00841
00842 return 1;
00843 }
00844
00845
00846
00847
00848
00849
00850
00851
00852 static int interpolationCounter = 0;
00853
00854
00855 static void setTrajCycleTime(double secs)
00856 {
00857 static int t;
00858
00859
00860 if (secs <= 0.0) {
00861 return;
00862 }
00863 MARK_EMCMOT_CONFIG_CHANGE();
00864
00865
00866
00867 emcmotConfig->interpolationRate =
00868 (int) (secs / emcmotConfig->servoCycleTime + 0.5);
00869
00870
00871 tpSetCycleTime(&queue, secs);
00872
00873
00874 for (t = 0; t < EMCMOT_MAX_AXIS; t++) {
00875 tpSetCycleTime(&freeAxis[t], secs);
00876 cubicSetInterpolationRate(&cubic[t], emcmotConfig->interpolationRate);
00877 }
00878
00879
00880 emcmotConfig->trajCycleTime = secs;
00881 }
00882
00883
00884 static void setServoCycleTime(double secs)
00885 {
00886 static int t;
00887
00888
00889 if (secs <= 0.0) {
00890 return;
00891 }
00892
00893 MARK_EMCMOT_CONFIG_CHANGE();
00894
00895
00896 emcmotConfig->interpolationRate =
00897 (int) (emcmotConfig->trajCycleTime / secs + 0.5);
00898
00899
00900 for (t = 0; t < EMCMOT_MAX_AXIS; t++) {
00901 cubicSetInterpolationRate(&cubic[t], emcmotConfig->interpolationRate);
00902 cubicSetSegmentTime(&cubic[t], secs);
00903 #ifndef STEPPER_MOTORS
00904 pidSetCycleTime(&emcmotConfig->pid[t], secs);
00905 #endif
00906 }
00907
00908
00909 emcmotConfig->servoCycleTime = secs;
00910
00911 #ifdef STEPPER_MOTORS
00912 smCyclesPerAxis = (int) (emcmotConfig->servoCycleTime / smCycleTime);
00913 #endif
00914 }
00915
00916
00917
00918
00919
00920 static int emcmotCommandHandler(void)
00921 {
00922 int axis;
00923 #ifdef rtlinux
00924 #ifdef RT_FIFO
00925 int err;
00926 #endif
00927 #endif
00928 int valid;
00929 #ifdef STEPPER_MOTORS
00930 double mag;
00931
00932 #endif
00933
00934
00935
00936 #if defined (rtlinux) && defined (RT_FIFO)
00937 while ((err =
00938 rtf_get(EMCMOT_COMMAND_RTF, &emcmotCommandBuffer,
00939 sizeof(EMCMOT_COMMAND))) == sizeof(EMCMOT_COMMAND)) {
00940
00941 #endif
00942
00943
00944 if (emcmotCommand->head != emcmotCommand->tail) {
00945 emcmotDebug->split++;
00946 return 0;
00947 }
00948
00949 if (emcmotCommand->commandNum != emcmotStatus->commandNumEcho) {
00950
00951 emcmotStatus->head++;
00952 emcmotDebug->head++;
00953
00954
00955 emcmotStatus->commandEcho = emcmotCommand->command;
00956 emcmotStatus->commandNumEcho = emcmotCommand->commandNum;
00957
00958
00959 emcmotStatus->commandStatus = EMCMOT_COMMAND_OK;
00960
00961
00962 if (emcmotStatus->logStarted &&
00963 emcmotStatus->logType == EMCMOT_LOG_TYPE_CMD) {
00964 ls.item.cmd.time = etime();
00965 ls.item.cmd.command = emcmotCommand->command;
00966 ls.item.cmd.commandNum = emcmotCommand->commandNum;
00967 #if defined (rtlinux) && defined (RT_FIFO)
00968 rtf_put(EMCMOT_LOG_RTF, &ls, sizeof(EMCMOT_LOG_STRUCT));
00969 #else
00970 emcmotLogAdd(emcmotLog, ls);
00971 emcmotStatus->logPoints = emcmotLog->howmany;
00972 #endif
00973 }
00974
00975
00976 switch (emcmotCommand->command) {
00977 case EMCMOT_FREE:
00978
00979
00980
00981
00982 coordinating = 0;
00983 break;
00984
00985 case EMCMOT_COORD:
00986
00987
00988
00989
00990 coordinating = 1;
00991 break;
00992
00993 case EMCMOT_SET_NUM_AXES:
00994 MARK_EMCMOT_CONFIG_CHANGE();
00995
00996
00997 axis = emcmotCommand->axis;
00998
00999
01000
01001
01002
01003 if
01004 (
01005 axis <= 0 ||
01006 axis > EMCMOT_MAX_AXIS
01007 ) {
01008 break;
01009 }
01010 NUM_AXES = axis;
01011 break;
01012
01013 case EMCMOT_SET_WORLD_HOME:
01014 worldHome = emcmotCommand->pos;
01015 break;
01016
01017 case EMCMOT_SET_JOINT_HOME:
01018 axis = emcmotCommand->axis;
01019 if (axis < 0 ||
01020 axis >= EMCMOT_MAX_AXIS) {
01021 break;
01022 }
01023 jointHome[axis] = emcmotCommand->offset;
01024 break;
01025
01026 case EMCMOT_SET_HOME_OFFSET:
01027 axis = emcmotCommand->axis;
01028 if (axis < 0 ||
01029 axis >= EMCMOT_MAX_AXIS) {
01030 break;
01031 }
01032 emcmotConfig->homeOffset[axis] = emcmotCommand->offset;
01033 break;
01034
01035 case EMCMOT_OVERRIDE_LIMITS:
01036 if (emcmotCommand->axis < 0) {
01037
01038 emcmotStatus->overrideLimits = 0;
01039 }
01040 else {
01041 emcmotStatus->overrideLimits = 1;
01042 }
01043 overriding = 0;
01044 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
01045 SET_AXIS_ERROR_FLAG(axis, 0);
01046 }
01047 break;
01048
01049 case EMCMOT_SET_TRAJ_CYCLE_TIME:
01050 MARK_EMCMOT_CONFIG_CHANGE();
01051
01052
01053
01054
01055
01056 setTrajCycleTime(emcmotCommand->cycleTime);
01057 break;
01058
01059 case EMCMOT_SET_SERVO_CYCLE_TIME:
01060 MARK_EMCMOT_CONFIG_CHANGE();
01061
01062
01063
01064
01065
01066
01067 setServoCycleTime(emcmotCommand->cycleTime);
01068 #ifdef rtlinux
01069 #ifdef USE_RTL2
01070 pthread_make_periodic_np(emcmotTask,
01071 gethrtime(),
01072 (hrtime_t) (HRTICKS_PER_SEC *
01073 emcmotConfig->servoCycleTime));
01074 #else
01075 rt_task_make_periodic(&emcmotTask,
01076 rt_get_time(),
01077 (RTIME) (RT_TICKS_PER_SEC *
01078 emcmotConfig->servoCycleTime));
01079 #endif
01080 #endif
01081 break;
01082
01083 case EMCMOT_SET_POSITION_LIMITS:
01084 MARK_EMCMOT_CONFIG_CHANGE();
01085
01086
01087 axis = emcmotCommand->axis;
01088 if (axis < 0 ||
01089 axis >= EMCMOT_MAX_AXIS) {
01090 break;
01091 }
01092 emcmotConfig->minLimit[axis] = emcmotCommand->minLimit;
01093 emcmotConfig->maxLimit[axis] = emcmotCommand->maxLimit;
01094 break;
01095
01096 case EMCMOT_SET_OUTPUT_LIMITS:
01097 MARK_EMCMOT_CONFIG_CHANGE();
01098
01099
01100 axis = emcmotCommand->axis;
01101 if (axis < 0 ||
01102 axis >= EMCMOT_MAX_AXIS) {
01103 break;
01104 }
01105
01106 emcmotConfig->minOutput[axis] = emcmotCommand->minLimit;
01107 emcmotConfig->maxOutput[axis] = emcmotCommand->maxLimit;
01108 break;
01109
01110 case EMCMOT_SET_OUTPUT_SCALE:
01111 axis = emcmotCommand->axis;
01112 if (axis < 0 ||
01113 axis >= EMCMOT_MAX_AXIS ||
01114 emcmotCommand->scale == 0) {
01115 break;
01116 }
01117 emcmotStatus->outputScale[axis] = emcmotCommand->scale;
01118 emcmotStatus->outputOffset[axis] = emcmotCommand->offset;
01119 inverseOutputScale[axis] = 1.0 / emcmotStatus->outputScale[axis];
01120 break;
01121
01122 case EMCMOT_SET_INPUT_SCALE:
01123
01124
01125
01126
01127
01128
01129
01130 axis = emcmotCommand->axis;
01131 if (axis < 0 ||
01132 axis >= EMCMOT_MAX_AXIS ||
01133 emcmotCommand->scale == 0.0) {
01134 break;
01135 }
01136
01137
01138
01139 oldInput[axis] = oldInput[axis] * emcmotStatus->inputScale[axis] +
01140 emcmotStatus->inputOffset[axis];
01141 oldInput[axis] = (oldInput[axis] - emcmotCommand->offset) /
01142 emcmotCommand->scale;
01143
01144
01145 emcmotStatus->inputScale[axis] = emcmotCommand->scale;
01146 emcmotStatus->inputOffset[axis] = emcmotCommand->offset;
01147 inverseInputScale[axis] = 1.0 / emcmotStatus->inputScale[axis];
01148
01149 #ifdef STEPPER_MOTORS
01150
01151
01152
01153 smStepsPerUnit[axis] = emcmotCommand->scale;
01154 mag = fabs(smStepsPerUnit[axis]);
01155 smMagUnitsPerStep[axis] = 1.0 / mag;
01156
01157 if (mag > smMaxStepsPerUnit) {
01158 smVPmax = smVPmax * mag / smMaxStepsPerUnit;
01159 smMaxStepsPerUnit = mag;
01160 }
01161
01162
01163
01164 smCycleTime = 0.5/smVPmax;
01165 smCyclesPerAxis = (int) (emcmotConfig->servoCycleTime / smCycleTime);
01166 #ifdef USE_RTL2
01167 pthread_make_periodic_np(smTask,
01168 gethrtime(),
01169 ((hrtime_t) (HRTICKS_PER_SEC * smCycleTime)));
01170 #else
01171 rt_task_make_periodic(&smTask,
01172 rt_get_time(),
01173 ((RTIME) (RT_TICKS_PER_SEC * smCycleTime)));
01174 #endif
01175 #endif
01176 break;
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187 case EMCMOT_SET_MAX_FERROR:
01188 MARK_EMCMOT_CONFIG_CHANGE();
01189 axis = emcmotCommand->axis;
01190 if (axis < 0 ||
01191 axis >= EMCMOT_MAX_AXIS ||
01192 emcmotCommand->maxFerror < 0.0) {
01193 break;
01194 }
01195 emcmotConfig->maxFerror[axis] = emcmotCommand->maxFerror;
01196 break;
01197
01198 case EMCMOT_SET_MIN_FERROR:
01199 MARK_EMCMOT_CONFIG_CHANGE();
01200 axis = emcmotCommand->axis;
01201 if (axis < 0 ||
01202 axis >= EMCMOT_MAX_AXIS ||
01203 emcmotCommand->minFerror < 0.0) {
01204 break;
01205 }
01206 emcmotConfig->minFerror[axis] = emcmotCommand->minFerror;
01207 break;
01208
01209 case EMCMOT_JOG_CONT:
01210
01211
01212
01213
01214
01215 axis = emcmotCommand->axis;
01216 if (axis < 0 ||
01217 axis >= EMCMOT_MAX_AXIS) {
01218 break;
01219 }
01220
01221
01222 if (GET_MOTION_COORD_FLAG() ||
01223 ! GET_MOTION_INPOS_FLAG() ||
01224 ! GET_MOTION_ENABLE_FLAG()) {
01225 SET_AXIS_ERROR_FLAG(axis, 1);
01226 break;
01227 }
01228
01229
01230 if (! checkJog(axis, emcmotCommand->vel)) {
01231 SET_AXIS_ERROR_FLAG(axis, 1);
01232 break;
01233 }
01234
01235 if (emcmotCommand->vel > 0.0) {
01236 if (GET_AXIS_HOMED_FLAG(axis)) {
01237 freePose.tran.x = emcmotConfig->maxLimit[axis];
01238 }
01239 else {
01240 freePose.tran.x = AXRANGE(axis);
01241 }
01242 }
01243 else {
01244 if (GET_AXIS_HOMED_FLAG(axis)) {
01245 freePose.tran.x = emcmotConfig->minLimit[axis];
01246 }
01247 else {
01248 freePose.tran.x = - AXRANGE(axis);
01249 }
01250 }
01251
01252 tpSetVmax(&freeAxis[axis], fabs(emcmotCommand->vel));
01253 tpAddLine(&freeAxis[axis], freePose);
01254 SET_AXIS_ERROR_FLAG(axis, 0);
01255
01256 break;
01257
01258 case EMCMOT_JOG_INCR:
01259
01260
01261
01262 axis = emcmotCommand->axis;
01263 if (axis < 0 ||
01264 axis >= EMCMOT_MAX_AXIS) {
01265 break;
01266 }
01267
01268
01269 if (GET_MOTION_COORD_FLAG() ||
01270 ! GET_MOTION_INPOS_FLAG() ||
01271 ! GET_MOTION_ENABLE_FLAG()) {
01272 SET_AXIS_ERROR_FLAG(axis, 1);
01273 break;
01274 }
01275
01276
01277 if (! checkJog(axis, emcmotCommand->vel)) {
01278 SET_AXIS_ERROR_FLAG(axis, 1);
01279 break;
01280 }
01281
01282 if (emcmotCommand->vel > 0.0) {
01283 freePose.tran.x = jointPos[axis] + emcmotCommand->offset;
01284 if (GET_AXIS_HOMED_FLAG(axis)) {
01285 if (freePose.tran.x > emcmotConfig->maxLimit[axis]) {
01286 freePose.tran.x = emcmotConfig->maxLimit[axis];
01287 }
01288 }
01289 }
01290 else {
01291 freePose.tran.x = jointPos[axis] - emcmotCommand->offset;
01292 if (GET_AXIS_HOMED_FLAG(axis)) {
01293 if (freePose.tran.x < emcmotConfig->minLimit[axis]) {
01294 freePose.tran.x = emcmotConfig->minLimit[axis];
01295 }
01296 }
01297 }
01298
01299 tpSetVmax(&freeAxis[axis], fabs(emcmotCommand->vel));
01300 tpAddLine(&freeAxis[axis], freePose);
01301 SET_AXIS_ERROR_FLAG(axis, 0);
01302
01303 break;
01304
01305 case EMCMOT_JOG_ABS:
01306
01307
01308
01309 axis = emcmotCommand->axis;
01310 if (axis < 0 ||
01311 axis >= EMCMOT_MAX_AXIS) {
01312 break;
01313 }
01314
01315
01316 if (GET_MOTION_COORD_FLAG() ||
01317 ! GET_MOTION_INPOS_FLAG() ||
01318 ! GET_MOTION_ENABLE_FLAG()) {
01319 SET_AXIS_ERROR_FLAG(axis, 1);
01320 break;
01321 }
01322
01323
01324 if (! checkJog(axis, emcmotCommand->vel)) {
01325 SET_AXIS_ERROR_FLAG(axis, 1);
01326 break;
01327 }
01328
01329 freePose.tran.x = emcmotCommand->offset;
01330 if (GET_AXIS_HOMED_FLAG(axis)) {
01331 if (freePose.tran.x > emcmotConfig->maxLimit[axis]) {
01332 freePose.tran.x = emcmotConfig->maxLimit[axis];
01333 }
01334 else if (freePose.tran.x < emcmotConfig->minLimit[axis]) {
01335 freePose.tran.x = emcmotConfig->minLimit[axis];
01336 }
01337 }
01338
01339 tpSetVmax(&freeAxis[axis], fabs(emcmotCommand->vel));
01340 tpAddLine(&freeAxis[axis], freePose);
01341 SET_AXIS_ERROR_FLAG(axis, 0);
01342
01343 break;
01344
01345 case EMCMOT_SET_TERM_COND:
01346
01347 tpSetTermCond(&queue, emcmotCommand->termCond);
01348 break;
01349
01350 case EMCMOT_SET_LINE:
01351
01352
01353 if (! GET_MOTION_COORD_FLAG() ||
01354 ! GET_MOTION_ENABLE_FLAG()) {
01355 reportError("Need to be enabled, in coord mode for linear move");
01356 emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_COMMAND;
01357 SET_MOTION_ERROR_FLAG(1);
01358 break;
01359 }
01360 else if (! inRange(emcmotCommand->pos)) {
01361 reportError("Linear move %d out of range",
01362 emcmotCommand->id);
01363 emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
01364 tpAbort(&queue);
01365 SET_MOTION_ERROR_FLAG(1);
01366 break;
01367 }
01368 else if (! checkLimits()) {
01369 reportError("Can't do linear move with limits exceeded");
01370 emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
01371 tpAbort(&queue);
01372 SET_MOTION_ERROR_FLAG(1);
01373 break;
01374 }
01375
01376
01377 tpSetId(&queue, emcmotCommand->id);
01378 if (-1 == tpAddLine(&queue, emcmotCommand->pos)) {
01379 reportError("Can't add linear move");
01380 emcmotStatus->commandStatus = EMCMOT_COMMAND_BAD_EXEC;
01381 tpAbort(&queue);
01382 SET_MOTION_ERROR_FLAG(1);
01383 break;
01384 }
01385 else {
01386 SET_MOTION_ERROR_FLAG(0);
01387 }
01388 break;
01389
01390 case EMCMOT_SET_CIRCLE:
01391
01392
01393 if (! GET_MOTION_COORD_FLAG() ||
01394 ! GET_MOTION_ENABLE_FLAG()) {
01395 reportError("Need to be enabled, in coord mode for circular move");
01396 emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_COMMAND;
01397 SET_MOTION_ERROR_FLAG(1);
01398 break;
01399 }
01400 else if (! inRange(emcmotCommand->pos)) {
01401 reportError("Circular move %d out of range",
01402 emcmotCommand->id);
01403 emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
01404 tpAbort(&queue);
01405 SET_MOTION_ERROR_FLAG(1);
01406 break;
01407 }
01408 else if (! checkLimits()) {
01409 reportError("Can't do circular move with limits exceeded");
01410 emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
01411 tpAbort(&queue);
01412 SET_MOTION_ERROR_FLAG(1);
01413 break;
01414 }
01415
01416
01417 tpSetId(&queue, emcmotCommand->id);
01418 if (-1 ==
01419 tpAddCircle(&queue, emcmotCommand->pos,
01420 emcmotCommand->center, emcmotCommand->normal,
01421 emcmotCommand->turn)) {
01422 reportError("Can't add circular move");
01423 emcmotStatus->commandStatus = EMCMOT_COMMAND_BAD_EXEC;
01424 tpAbort(&queue);
01425 SET_MOTION_ERROR_FLAG(1);
01426 break;
01427 }
01428 else {
01429 SET_MOTION_ERROR_FLAG(0);
01430 }
01431 break;
01432
01433 case EMCMOT_SET_VEL:
01434
01435
01436 emcmotStatus->vel = emcmotCommand->vel;
01437 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
01438 tpSetVmax(&freeAxis[axis], emcmotStatus->vel);
01439 }
01440 tpSetVmax(&queue, emcmotStatus->vel);
01441 break;
01442
01443
01444 case EMCMOT_SET_AXIS_VEL_LIMIT:
01445
01446 axis = emcmotCommand->axis;
01447 if (axis < 0 ||
01448 axis >= EMCMOT_MAX_AXIS) {
01449 break;
01450 }
01451 tpSetVlimit(&freeAxis[axis], emcmotCommand->vel);
01452 emcmotConfig->axisLimitVel[axis] = emcmotCommand->vel;
01453
01454 break;
01455
01456 case EMCMOT_SET_VEL_LIMIT:
01457
01458
01459 #ifdef STEPPER_MOTORS
01460
01461
01462 smVPmax = smVPmax * emcmotCommand->vel / emcmotConfig->limitVel;
01463
01464
01465
01466 smCycleTime = 0.5/smVPmax;
01467 smCyclesPerAxis = (int) (emcmotConfig->servoCycleTime / smCycleTime);
01468 #ifdef USE_RTL2
01469 pthread_make_periodic_np(smTask,
01470 gethrtime(),
01471 ((hrtime_t) (HRTICKS_PER_SEC * smCycleTime)));
01472 #else
01473 rt_task_make_periodic(&smTask,
01474 rt_get_time(),
01475 ((RTIME) (RT_TICKS_PER_SEC * smCycleTime)));
01476 #endif
01477 #endif
01478 emcmotConfig->limitVel = emcmotCommand->vel;
01479 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
01480 tpSetVlimit(&freeAxis[axis], emcmotConfig->limitVel);
01481 }
01482 tpSetVlimit(&queue, emcmotConfig->limitVel);
01483
01484 bigVel = 10.0 * emcmotConfig->limitVel;
01485 break;
01486
01487 case EMCMOT_SET_HOMING_VEL:
01488
01489
01490
01491
01492
01493 axis = emcmotCommand->axis;
01494 if (axis < 0 ||
01495 axis >= EMCMOT_MAX_AXIS) {
01496 break;
01497 }
01498
01499 if (emcmotCommand->vel < 0.0) {
01500 emcmotConfig->homingVel[axis] = - emcmotCommand->vel;
01501 SET_AXIS_HOMING_POLARITY(axis, 0);
01502 }
01503 else {
01504 emcmotConfig->homingVel[axis] = emcmotCommand->vel;
01505 SET_AXIS_HOMING_POLARITY(axis, 1);
01506 }
01507 break;
01508
01509 case EMCMOT_SET_ACC:
01510
01511
01512 emcmotStatus->acc = emcmotCommand->acc;
01513 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
01514 tpSetAmax(&freeAxis[axis], emcmotStatus->acc);
01515 }
01516 tpSetAmax(&queue, emcmotStatus->acc);
01517 break;
01518
01519 case EMCMOT_PAUSE:
01520
01521
01522 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
01523 tpPause(&freeAxis[axis]);
01524 }
01525 tpPause(&queue);
01526 emcmotStatus->paused = 1;
01527 break;
01528
01529 case EMCMOT_RESUME:
01530
01531
01532 stepping = 0;
01533 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
01534 tpResume(&freeAxis[axis]);
01535 }
01536 tpResume(&queue);
01537 emcmotStatus->paused = 0;
01538 break;
01539
01540 case EMCMOT_STEP:
01541
01542
01543 idForStep = emcmotStatus->id;
01544 stepping = 1;
01545 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
01546 tpResume(&freeAxis[axis]);
01547 }
01548 tpResume(&queue);
01549 emcmotStatus->paused = 0;
01550 break;
01551
01552 case EMCMOT_SCALE:
01553
01554
01555 if (emcmotCommand->scale < 0.0) {
01556 emcmotCommand->scale = 0.0;
01557 }
01558 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
01559 tpSetVscale(&freeAxis[axis], emcmotCommand->scale);
01560 emcmotStatus->axVscale[axis] = emcmotCommand->scale;
01561 }
01562 tpSetVscale(&queue, emcmotCommand->scale);
01563 emcmotStatus->qVscale = emcmotCommand->scale;
01564 break;
01565
01566 case EMCMOT_ABORT:
01567
01568
01569
01570 if (GET_MOTION_COORD_FLAG()) {
01571 tpAbort(&queue);
01572 SET_MOTION_ERROR_FLAG(0);
01573 }
01574 else {
01575
01576 axis = emcmotCommand->axis;
01577 if (axis < 0 ||
01578 axis >= EMCMOT_MAX_AXIS) {
01579 break;
01580 }
01581 tpAbort(&freeAxis[axis]);
01582 SET_AXIS_HOMING_FLAG(axis, 0);
01583 SET_AXIS_ERROR_FLAG(axis, 0);
01584 }
01585 break;
01586
01587 case EMCMOT_DISABLE:
01588
01589
01590
01591
01592 enabling = 0;
01593 break;
01594
01595 case EMCMOT_ENABLE:
01596
01597
01598
01599
01600 enabling = 1;
01601 break;
01602
01603 case EMCMOT_SET_PID:
01604
01605 axis = emcmotCommand->axis;
01606 if (axis < 0 ||
01607 axis >= EMCMOT_MAX_AXIS) {
01608 break;
01609 }
01610
01611
01612 emcmotConfig->pid[axis].p = emcmotCommand->pid.p;
01613 emcmotConfig->pid[axis].i = emcmotCommand->pid.i;
01614 emcmotConfig->pid[axis].d = emcmotCommand->pid.d;
01615 emcmotConfig->pid[axis].ff0 = emcmotCommand->pid.ff0;
01616 emcmotConfig->pid[axis].ff1 = emcmotCommand->pid.ff1;
01617 emcmotConfig->pid[axis].ff2 = emcmotCommand->pid.ff2;
01618 emcmotConfig->pid[axis].backlash = emcmotCommand->pid.backlash;
01619 emcmotConfig->pid[axis].bias = emcmotCommand->pid.bias;
01620 emcmotConfig->pid[axis].maxError = emcmotCommand->pid.maxError;
01621 emcmotConfig->pid[axis].deadband = emcmotCommand->pid.deadband;
01622 break;
01623
01624 case EMCMOT_ACTIVATE_AXIS:
01625
01626
01627
01628 axis = emcmotCommand->axis;
01629 if (axis < 0 ||
01630 axis >= EMCMOT_MAX_AXIS) {
01631 break;
01632 }
01633 SET_AXIS_ACTIVE_FLAG(axis, 1);
01634 break;
01635
01636 case EMCMOT_DEACTIVATE_AXIS:
01637
01638
01639
01640 axis = emcmotCommand->axis;
01641 if (axis < 0 ||
01642 axis >= EMCMOT_MAX_AXIS) {
01643 break;
01644 }
01645 SET_AXIS_ACTIVE_FLAG(axis, 0);
01646 break;
01647
01648 case EMCMOT_ENABLE_AMPLIFIER:
01649
01650
01651 axis = emcmotCommand->axis;
01652 if (axis < 0 ||
01653 axis >= EMCMOT_MAX_AXIS) {
01654 break;
01655 }
01656 extAmpEnable(axis, GET_AXIS_ENABLE_POLARITY(axis));
01657 break;
01658
01659 case EMCMOT_DISABLE_AMPLIFIER:
01660
01661
01662
01663 axis = emcmotCommand->axis;
01664 if (axis < 0 ||
01665 axis >= EMCMOT_MAX_AXIS) {
01666 break;
01667 }
01668 extAmpEnable(axis, ! GET_AXIS_ENABLE_POLARITY(axis));
01669 break;
01670
01671 case EMCMOT_OPEN_LOG:
01672
01673 axis = emcmotCommand->axis;
01674 valid = 0;
01675 if (emcmotCommand->logSize > 0 &&
01676 emcmotCommand->logSize <= EMCMOT_LOG_MAX) {
01677
01678 switch (emcmotCommand->logType) {
01679 case EMCMOT_LOG_TYPE_AXIS_POS:
01680 case EMCMOT_LOG_TYPE_AXIS_VEL:
01681 case EMCMOT_LOG_TYPE_POS_VOLTAGE:
01682 if (axis >= 0 &&
01683 axis < EMCMOT_MAX_AXIS) {
01684 loggingAxis = axis;
01685 valid = 1;
01686 }
01687 break;
01688
01689 default:
01690 valid = 1;
01691 break;
01692 }
01693 }
01694
01695 if (valid) {
01696
01697 #if defined (rtlinux) && defined (RT_FIFO)
01698 if (-1 ==
01699 rtf_create(EMCMOT_LOG_RTF,
01700 emcmotCommand->logSize *
01701 sizeof(EMCMOT_LOG_STRUCT))) {
01702
01703 break;
01704 }
01705 #else
01706 emcmotLogInit(emcmotLog,
01707 emcmotCommand->logType,
01708 emcmotCommand->logSize);
01709 #endif
01710 emcmotStatus->logOpen = 1;
01711 emcmotStatus->logStarted = 0;
01712 emcmotStatus->logSize = emcmotCommand->logSize;
01713 emcmotStatus->logSkip = emcmotCommand->logSkip;
01714 emcmotStatus->logType = emcmotCommand->logType;
01715 }
01716 break;
01717
01718 case EMCMOT_START_LOG:
01719
01720
01721 if (emcmotStatus->logType == EMCMOT_LOG_TYPE_POS_VOLTAGE) {
01722 break;
01723 }
01724 if (emcmotStatus->logOpen) {
01725 emcmotStatus->logStarted = 1;
01726 logSkip = 0;
01727 }
01728 break;
01729
01730 case EMCMOT_STOP_LOG:
01731
01732 emcmotStatus->logStarted = 0;
01733 break;
01734
01735 case EMCMOT_CLOSE_LOG:
01736 #if defined (rtlinux) && defined (RT_FIFO)
01737 rtf_destroy(EMCMOT_LOG_RTF);
01738 #endif
01739 emcmotStatus->logOpen = 0;
01740 emcmotStatus->logStarted = 0;
01741 emcmotStatus->logSize = 0;
01742 emcmotStatus->logSkip = 0;
01743 emcmotStatus->logType = 0;
01744 break;
01745
01746 case EMCMOT_DAC_OUT:
01747
01748
01749 axis = emcmotCommand->axis;
01750 if (axis < 0 ||
01751 axis >= EMCMOT_MAX_AXIS) {
01752 break;
01753 }
01754
01755 if (emcmotStatus->logType == EMCMOT_LOG_TYPE_POS_VOLTAGE &&
01756 loggingAxis == axis &&
01757 emcmotStatus->logOpen != 0) {
01758 emcmotStatus->logStarted = 1;
01759 logSkip = 0;
01760 }
01761 emcmotStatus->output[axis] = emcmotCommand->dacOut;
01762 break;
01763
01764 case EMCMOT_HOME:
01765
01766
01767
01768 axis = emcmotCommand->axis;
01769 if (axis < 0 ||
01770 axis >= EMCMOT_MAX_AXIS) {
01771 break;
01772 }
01773 if (GET_MOTION_COORD_FLAG() ||
01774 ! GET_MOTION_ENABLE_FLAG()) {
01775 break;
01776 }
01777
01778 if (GET_AXIS_HOMING_POLARITY(axis)) {
01779 freePose.tran.x = + 2.0 * AXRANGE(axis);
01780 }
01781 else {
01782 freePose.tran.x = - 2.0 * AXRANGE(axis);
01783 }
01784
01785 tpSetVmax(&freeAxis[axis], emcmotConfig->homingVel[axis]);
01786 tpAddLine(&freeAxis[axis], freePose);
01787 waitingForLatch[axis] = 1;
01788 SET_AXIS_HOMING_FLAG(axis, 1);
01789 SET_AXIS_HOMED_FLAG(axis, 0);
01790 break;
01791
01792 case EMCMOT_ENABLE_WATCHDOG:
01793 wdEnabling = 1;
01794 wdWait = emcmotCommand->wdWait;
01795 if (wdWait < 0) {
01796 wdWait = 0;
01797 }
01798 break;
01799
01800 case EMCMOT_DISABLE_WATCHDOG:
01801 wdEnabling = 0;
01802 break;
01803
01804 case EMCMOT_SET_POLARITY:
01805 axis = emcmotCommand->axis;
01806 if (axis < 0 ||
01807 axis >= EMCMOT_MAX_AXIS) {
01808 break;
01809 }
01810 if (emcmotCommand->level) {
01811
01812 emcmotConfig->axisPolarity[axis] |= emcmotCommand->axisFlag;
01813 }
01814 else {
01815
01816 emcmotConfig->axisPolarity[axis] &= ~emcmotCommand->axisFlag;
01817 }
01818 break;
01819
01820 #ifdef ENABLE_PROBING
01821 case EMCMOT_SET_PROBE_INDEX:
01822 emcmotConfig->probeIndex = emcmotCommand->probeIndex;
01823 break;
01824
01825 case EMCMOT_SET_PROBE_POLARITY:
01826 emcmotConfig->probePolarity = emcmotCommand->level;
01827 break;
01828
01829 case EMCMOT_CLEAR_PROBE_FLAGS:
01830 emcmotStatus->probeTripped = 0;
01831 emcmotStatus->probing = 1;
01832 break;
01833
01834 case EMCMOT_PROBE:
01835
01836
01837
01838 if (! GET_MOTION_COORD_FLAG() ||
01839 ! GET_MOTION_ENABLE_FLAG()) {
01840 reportError("Need to be enabled, in coord mode for linear move");
01841 emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_COMMAND;
01842 SET_MOTION_ERROR_FLAG(1);
01843 break;
01844 }
01845 else if (! inRange(emcmotCommand->pos)) {
01846 reportError("Linear move %d out of range",
01847 emcmotCommand->id);
01848 emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
01849 tpAbort(&queue);
01850 SET_MOTION_ERROR_FLAG(1);
01851 break;
01852 }
01853 else if (! checkLimits()) {
01854 reportError("Can't do linear move with limits exceeded");
01855 emcmotStatus->commandStatus = EMCMOT_COMMAND_INVALID_PARAMS;
01856 tpAbort(&queue);
01857 SET_MOTION_ERROR_FLAG(1);
01858 break;
01859 }
01860
01861
01862 tpSetId(&queue, emcmotCommand->id);
01863 if (-1 == tpAddLine(&queue, emcmotCommand->pos)) {
01864 reportError("Can't add linear move");
01865 emcmotStatus->commandStatus = EMCMOT_COMMAND_BAD_EXEC;
01866 tpAbort(&queue);
01867 SET_MOTION_ERROR_FLAG(1);
01868 break;
01869 }
01870 else {
01871 emcmotStatus->probeTripped = 0;
01872 emcmotStatus->probing = 1;
01873 SET_MOTION_ERROR_FLAG(0);
01874 }
01875 break;
01876 #endif
01877
01878 default:
01879 reportError("Unrecognized command %d", emcmotCommand->command);
01880 emcmotStatus->commandStatus = EMCMOT_COMMAND_UNKNOWN_COMMAND;
01881 break;
01882 }
01883
01884
01885 emcmotStatus->tail = emcmotStatus->head;
01886 emcmotConfig->tail = emcmotConfig->head;
01887 emcmotDebug->tail = emcmotDebug->head;
01888
01889 }
01890
01891 #if defined (rtlinux) && defined (RT_FIFO)
01892 }
01893
01894 if (err != 0) {
01895 return -1;
01896 }
01897
01898 #endif
01899
01900 return 0;
01901 }
01902
01903
01904 int EMCMOT_NO_FORWARD_KINEMATICS = 0;
01905
01906
01907
01908
01909
01910
01911
01912
01913 #ifdef USE_RTL2
01914 static void *emcmotController(void *arg)
01915 #else
01916 static void emcmotController(int arg)
01917 #endif
01918 {
01919 double start, end, delta;
01920 int homeFlag;
01921 int axis;
01922 int t;
01923 int isLimit;
01924 int whichCycle;
01925 int fault;
01926 double numres;
01927 double thisFerror[EMCMOT_MAX_AXIS];
01928 double limitFerror;
01929 double magFerror;
01930 #ifdef STEPPER_MOTORS
01931 double bcomp[EMCMOT_MAX_AXIS];
01932 char bcompdir[EMCMOT_MAX_AXIS];
01933 double bcompincr[EMCMOT_MAX_AXIS];
01934 double dsteps;
01935 double oldbcomp;
01936
01937 char bac_done[EMCMOT_MAX_AXIS];
01938 double bac_d[EMCMOT_MAX_AXIS];
01939 double bac_di[EMCMOT_MAX_AXIS];
01940 double bac_D[EMCMOT_MAX_AXIS];
01941 double bac_halfD[EMCMOT_MAX_AXIS];
01942 double bac_incrincr[EMCMOT_MAX_AXIS];
01943 double bac_incr[EMCMOT_MAX_AXIS];
01944 #endif
01945 char finalHome[EMCMOT_MAX_AXIS];
01946
01947 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
01948 #ifdef STEPPER_MOTORS
01949 bcomp[axis] = 0.0;
01950 bcompdir[axis] = 0;
01951 bcompincr[axis] = 0.0;
01952 bac_done[axis] = 1;
01953 bac_d[axis] = 0.0;
01954 bac_di[axis] = 0.0;
01955 bac_D[axis] = 0.0;
01956 bac_halfD[axis] = 0.0;
01957 bac_incrincr[axis] = 0.0;
01958 bac_incr[axis] = 0.0;
01959 #endif
01960 finalHome[axis] = 0;
01961 }
01962
01963 #ifdef rtlinux
01964 for (;;) {
01965 #endif
01966
01967 #ifdef rtlinux
01968
01969
01970 if (wdEnabling && ! wdEnabled) {
01971
01972 wdCount = wdWait;
01973 wdToggle = 0;
01974 wdEnabled = 1;
01975 }
01976 if (! wdEnabling && wdEnabled) {
01977
01978
01979 soundByte = inb(SOUND_PORT);
01980 soundByte &= ~SOUND_MASK;
01981 outb(soundByte, SOUND_PORT);
01982 wdEnabled = 0;
01983 }
01984
01985 if (wdEnabled && wdCount-- <= 0) {
01986 soundByte = inb(SOUND_PORT);
01987 wdToggle = ! wdToggle;
01988 if (wdToggle) {
01989 soundByte |= SOUND_MASK;
01990 }
01991 else {
01992 soundByte &= ~SOUND_MASK;
01993 }
01994 outb(soundByte, SOUND_PORT);
01995 wdCount = wdWait;
01996 }
01997 #endif
01998
01999
02000 start = etime();
02001
02002
02003
02004 #ifndef RT_FIFO
02005 emcmotCommandHandler();
02006
02007 #endif
02008
02009
02010 emcmotStatus->head++;
02011 emcmotDebug->head++;
02012
02013
02014
02015 #ifndef STEPPER_MOTORS
02016
02017
02018
02019 extEncoderReadAll(EMCMOT_MAX_AXIS, rawInput);
02020 #endif
02021
02022
02023 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02024 #ifdef STEPPER_MOTORS
02025
02026 rawInput[axis] = (double) emcmotDebug->stepperCount[axis] -
02027 bcompincr[axis] * smStepsPerUnit[axis];
02028 #endif
02029
02030
02031 oldInput[axis] = emcmotStatus->input[axis];
02032
02033 emcmotStatus->input[axis] =
02034 (rawInput[axis] - emcmotStatus->inputOffset[axis]) *
02035 inverseInputScale[axis];
02036
02037 #ifndef STEPPER_MOTORS
02038
02039 if (fabs(emcmotStatus->input[axis] - oldInput[axis]) /
02040 emcmotConfig->servoCycleTime > bigVel) {
02041
02042 emcmotStatus->input[axis] = oldInput[axis];
02043 }
02044 #endif
02045
02046
02047
02048
02049
02050
02051 if (GET_AXIS_ACTIVE_FLAG(axis)) {
02052 extMaxLimitSwitchRead(axis, &isLimit);
02053 if (isLimit == GET_AXIS_PHL_POLARITY(axis)) {
02054 if (++maxLimitSwitchCount[axis] > LIMIT_SWITCH_DEBOUNCE) {
02055 SET_AXIS_PHL_FLAG(axis, 1);
02056 maxLimitSwitchCount[axis] = LIMIT_SWITCH_DEBOUNCE;
02057 if (emcmotStatus->overrideLimits ||
02058 isHoming()) {
02059 }
02060 else {
02061 SET_AXIS_ERROR_FLAG(axis, 1);
02062 enabling = 0;
02063 }
02064 }
02065 }
02066 else {
02067 SET_AXIS_PHL_FLAG(axis, 0);
02068 maxLimitSwitchCount[axis] = 0;
02069 }
02070 }
02071 if (GET_AXIS_ACTIVE_FLAG(axis)) {
02072 extMinLimitSwitchRead(axis, &isLimit);
02073 if (isLimit == GET_AXIS_NHL_POLARITY(axis)) {
02074 if (++minLimitSwitchCount[axis] > LIMIT_SWITCH_DEBOUNCE) {
02075 SET_AXIS_NHL_FLAG(axis, 1);
02076 minLimitSwitchCount[axis] = LIMIT_SWITCH_DEBOUNCE;
02077 if (emcmotStatus->overrideLimits ||
02078 isHoming()) {
02079 }
02080 else {
02081 SET_AXIS_ERROR_FLAG(axis, 1);
02082 enabling = 0;
02083 }
02084 }
02085 }
02086 else {
02087 SET_AXIS_NHL_FLAG(axis, 0);
02088 minLimitSwitchCount[axis] = 0;
02089 }
02090 }
02091
02092 if (GET_AXIS_ACTIVE_FLAG(axis) &&
02093 GET_AXIS_ENABLE_FLAG(axis)) {
02094 extAmpFault(axis, &fault);
02095 if (fault == GET_AXIS_FAULT_POLARITY(axis)) {
02096 if (++ampFaultCount[axis] > AMP_FAULT_DEBOUNCE) {
02097 SET_AXIS_ERROR_FLAG(axis, 1);
02098 SET_AXIS_FAULT_FLAG(axis, 1);
02099 ampFaultCount[axis] = AMP_FAULT_DEBOUNCE;
02100 enabling = 0;
02101 }
02102 }
02103 else {
02104 SET_AXIS_FAULT_FLAG(axis, 0);
02105 ampFaultCount[axis] = 0;
02106 }
02107 }
02108
02109
02110
02111 if (GET_AXIS_ACTIVE_FLAG(axis)) {
02112 extHomeSwitchRead(axis, &homeFlag);
02113 if (homeFlag == GET_AXIS_HOME_SWITCH_POLARITY(axis)) {
02114 SET_AXIS_HOME_SWITCH_FLAG(axis, 1);
02115 }
02116 else {
02117 SET_AXIS_HOME_SWITCH_FLAG(axis, 0);
02118 }
02119 }
02120
02121 }
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132 if (! enabling && GET_MOTION_ENABLE_FLAG()) {
02133
02134 tpClear(&queue);
02135 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02136 tpClear(&freeAxis[axis]);
02137 cubicDrain(&cubic[axis]);
02138 if (GET_AXIS_ACTIVE_FLAG(axis)) {
02139 extAmpEnable(axis, ! GET_AXIS_ENABLE_POLARITY(axis));
02140 SET_AXIS_ENABLE_FLAG(axis, 0);
02141 SET_AXIS_HOMING_FLAG(axis, 0);
02142 emcmotStatus->output[axis] = 0.0;
02143 }
02144
02145
02146 }
02147
02148
02149
02150
02151 interpolationCounter = 0;
02152 #ifdef STEPPER_MOTORS
02153 smInhibit = 1;
02154 #endif
02155 SET_MOTION_ENABLE_FLAG(0);
02156
02157
02158 }
02159
02160
02161 if (enabling && ! GET_MOTION_ENABLE_FLAG()) {
02162 tpSetPos(&queue, emcmotStatus->pos);
02163 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02164 freePose.tran.x = jointPos[axis];
02165 tpSetPos(&freeAxis[axis], freePose);
02166 #ifndef STEPPER_MOTORS
02167 pidReset(&emcmotConfig->pid[axis]);
02168 #endif
02169 if (GET_AXIS_ACTIVE_FLAG(axis)) {
02170 extAmpEnable(axis, GET_AXIS_ENABLE_POLARITY(axis));
02171 SET_AXIS_ENABLE_FLAG(axis, 1);
02172 SET_AXIS_HOMING_FLAG(axis, 0);
02173 }
02174
02175 SET_AXIS_ERROR_FLAG(axis, 0);
02176 }
02177 #ifdef STEPPER_MOTORS
02178 smInhibit = 0;
02179 #endif
02180 SET_MOTION_ENABLE_FLAG(1);
02181
02182 SET_MOTION_ERROR_FLAG(0);
02183 }
02184
02185
02186 if (coordinating && ! GET_MOTION_COORD_FLAG()) {
02187 if (GET_MOTION_INPOS_FLAG()) {
02188
02189 tpSetPos(&queue, emcmotStatus->pos);
02190
02191 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02192 cubicDrain(&cubic[axis]);
02193 }
02194
02195 overriding = 0;
02196 emcmotStatus->overrideLimits = 0;
02197 SET_MOTION_COORD_FLAG(1);
02198 SET_MOTION_ERROR_FLAG(0);
02199 }
02200 else {
02201
02202 coordinating = 0;
02203 }
02204 }
02205
02206
02207 if (! coordinating && GET_MOTION_COORD_FLAG()) {
02208 if (GET_MOTION_INPOS_FLAG()) {
02209 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02210
02211 freePose.tran.x = jointPos[axis];
02212 tpSetPos(&freeAxis[axis], freePose);
02213
02214 cubicDrain(&cubic[axis]);
02215 }
02216 SET_MOTION_COORD_FLAG(0);
02217 SET_MOTION_ERROR_FLAG(0);
02218 }
02219 else {
02220
02221 coordinating = 1;
02222 }
02223 }
02224
02225
02226 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02227 if (GET_AXIS_HOMING_FLAG(axis)) {
02228 if (tpIsDone(&freeAxis[axis])) {
02229
02230 if (finalHome[axis]) {
02231
02232 finalHome[axis] = 0;
02233
02234
02235
02236
02237
02238
02239 kinematicsHome(&worldHome, jointHome, &fflags, &iflags);
02240
02241
02242
02243
02244
02245
02246
02247 emcmotStatus->inputOffset[axis] = rawInput[axis] -
02248 jointHome[axis] * emcmotStatus->inputScale[axis];
02249
02250
02251
02252 emcmotStatus->input[axis] = jointHome[axis];
02253 oldInput[axis] = emcmotStatus->input[axis];
02254
02255
02256 cubicOffset(&cubic[axis], jointHome[axis] - coarseJointPos[axis]);
02257
02258
02259 jointPos[axis] = jointHome[axis];
02260 freePose.tran.x = jointHome[axis];
02261 tpSetPos(&freeAxis[axis], freePose);
02262
02263 SET_AXIS_HOMING_FLAG(axis, 0);
02264 SET_AXIS_HOMED_FLAG(axis, 1);
02265
02266
02267
02268 allHomed = 1;
02269 for (t = 0; t < EMCMOT_MAX_AXIS; t++) {
02270 if (GET_AXIS_ACTIVE_FLAG(t) &&
02271 ! GET_AXIS_HOMED_FLAG(t)) {
02272
02273 allHomed = 0;
02274 break;
02275 }
02276 }
02277
02278 if (allHomed) {
02279 emcmotStatus->pos = worldHome;
02280 emcmotStatus->actualPos = worldHome;
02281 }
02282 }
02283 else {
02284
02285 finalHome[axis] = 1;
02286
02287 freePose.tran.x =
02288 (saveLatch[axis] - emcmotStatus->inputOffset[axis]) *
02289 inverseInputScale[axis] +
02290 emcmotConfig->homeOffset[axis];
02291 tpAddLine(&freeAxis[axis], freePose);
02292 }
02293 }
02294 }
02295 }
02296
02297
02298
02299
02300
02301
02302
02303 whichCycle = 0;
02304 if (GET_MOTION_ENABLE_FLAG()) {
02305
02306 whichCycle = 1;
02307
02308
02309 while (cubicNeedNextPoint(&cubic[0])) {
02310
02311
02312
02313
02314
02315 if (GET_MOTION_COORD_FLAG()) {
02316
02317
02318
02319
02320
02321
02322
02323 whichCycle = 2;
02324
02325
02326 tpRunCycle(&queue);
02327
02328
02329 emcmotStatus->pos = tpGetPos(&queue);
02330
02331
02332 kinematicsInverse(&emcmotStatus->pos, coarseJointPos, &iflags, &fflags);
02333
02334
02335
02336
02337 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02338 cubicAddPoint(&cubic[axis], coarseJointPos[axis]);
02339 }
02340
02341
02342
02343
02344 if (EMCMOT_NO_FORWARD_KINEMATICS) {
02345
02346 emcmotStatus->actualPos = emcmotStatus->pos;
02347 }
02348 else {
02349 kinematicsForward(emcmotStatus->input, &emcmotStatus->actualPos, &fflags, &iflags);
02350 }
02351
02352
02353
02354
02355 }
02356 else {
02357
02358 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02359
02360
02361
02362
02363 whichCycle = 2;
02364
02365
02366 tpRunCycle(&freeAxis[axis]);
02367
02368
02369
02370
02371 coarseJointPos[axis] = tpGetPos(&freeAxis[axis]).tran.x;
02372
02373
02374
02375
02376 cubicAddPoint(&cubic[axis], coarseJointPos[axis]);
02377
02378 }
02379
02380 if (EMCMOT_NO_FORWARD_KINEMATICS) {
02381
02382 }
02383 else {
02384
02385
02386 kinematicsForward(emcmotStatus->input, &emcmotStatus->actualPos, &fflags, &iflags);
02387
02388
02389
02390
02391
02392
02393
02394 kinematicsForward(coarseJointPos, &emcmotStatus->pos, &fflags, &iflags);
02395 }
02396
02397
02398
02399
02400 }
02401 }
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429 onLimit = 0;
02430 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02431 SET_AXIS_PSL_FLAG(axis, 0);
02432 SET_AXIS_NSL_FLAG(axis, 0);
02433 if (GET_AXIS_HOMED_FLAG(axis)) {
02434 if (coarseJointPos[axis] > emcmotConfig->maxLimit[axis]) {
02435 SET_AXIS_ERROR_FLAG(axis, 1);
02436 SET_AXIS_PSL_FLAG(axis, 1);
02437 onLimit = 1;
02438 }
02439 else if (coarseJointPos[axis] < emcmotConfig->minLimit[axis]) {
02440 SET_AXIS_ERROR_FLAG(axis, 1);
02441 SET_AXIS_NSL_FLAG(axis, 1);
02442 }
02443 }
02444 }
02445
02446
02447
02448
02449
02450
02451 if (onLimit) {
02452 if (! wasOnLimit) {
02453
02454 tpAbort(&queue);
02455 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02456 tpAbort(&freeAxis[axis]);
02457 wasOnLimit = 1;
02458 }
02459 }
02460
02461 }
02462 else {
02463
02464
02465 wasOnLimit = 0;
02466 }
02467
02468 if (whichCycle == 2) {
02469
02470
02471 logIt = 0;
02472
02473 if (emcmotStatus->logStarted &&
02474 emcmotStatus->logSkip >= 0) {
02475
02476
02477 newVel.tran.x = (emcmotStatus->pos.tran.x - oldPos.tran.x) /
02478 emcmotConfig->trajCycleTime;
02479 newVel.tran.y = (emcmotStatus->pos.tran.y - oldPos.tran.y) /
02480 emcmotConfig->trajCycleTime;
02481 newVel.tran.z = (emcmotStatus->pos.tran.z - oldPos.tran.z) /
02482 emcmotConfig->trajCycleTime;
02483 oldPos = emcmotStatus->pos;
02484 newAcc.tran.x = (newVel.tran.x - oldVel.tran.x) /
02485 emcmotConfig->trajCycleTime;
02486 newAcc.tran.y = (newVel.tran.y - oldVel.tran.y) /
02487 emcmotConfig->trajCycleTime;
02488 newAcc.tran.z = (newVel.tran.z - oldVel.tran.z) /
02489 emcmotConfig->trajCycleTime;
02490 oldVel = newVel;
02491
02492
02493 ls.type = emcmotStatus->logType;
02494
02495
02496 switch (emcmotStatus->logType) {
02497
02498 case EMCMOT_LOG_TYPE_TRAJ_POS:
02499 if (logSkip-- <= 0) {
02500 ls.item.trajPos.time = start;
02501 ls.item.trajPos.pos = emcmotStatus->pos.tran;
02502 logSkip = emcmotStatus->logSkip;
02503 logIt = 1;
02504 }
02505 break;
02506
02507 case EMCMOT_LOG_TYPE_TRAJ_VEL:
02508 if (logSkip-- <= 0) {
02509 ls.item.trajVel.time = start;
02510 ls.item.trajVel.vel = newVel.tran;
02511 pmCartMag(newVel.tran, &ls.item.trajVel.mag);
02512 logSkip = emcmotStatus->logSkip;
02513 logIt = 1;
02514 }
02515 break;
02516
02517 case EMCMOT_LOG_TYPE_TRAJ_ACC:
02518 if (logSkip-- <= 0) {
02519 ls.item.trajAcc.time = start;
02520 ls.item.trajAcc.acc = newAcc.tran;
02521 pmCartMag(newAcc.tran, &ls.item.trajAcc.mag);
02522 logSkip = emcmotStatus->logSkip;
02523 logIt = 1;
02524 }
02525 break;
02526
02527 default:
02528 break;
02529 }
02530
02531
02532 #if defined (rtlinux) && defined (RT_FIFO)
02533 if (logIt) {
02534 rtf_put(EMCMOT_LOG_RTF, &ls, sizeof(EMCMOT_LOG_STRUCT));
02535
02536 logIt = 0;
02537 }
02538 #else
02539 if (logIt) {
02540 emcmotLogAdd(emcmotLog, ls);
02541 emcmotStatus->logPoints = emcmotLog->howmany;
02542 logIt = 0;
02543 }
02544 #endif
02545 }
02546
02547 }
02548
02549
02550 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02551
02552 oldJointPos[axis] = jointPos[axis];
02553 jointPos[axis] = cubicInterpolate(&cubic[axis], 0, 0, 0, 0);
02554
02555 numres = jointPos[axis] * emcmotStatus->inputScale[axis];
02556 if (numres < 0.0) {
02557 jointPos[axis] = inverseInputScale[axis] * ((int) (numres - 0.5));
02558 }
02559 else {
02560 jointPos[axis] = inverseInputScale[axis] * ((int) (numres + 0.5));
02561 }
02562 jointVel[axis] = (jointPos[axis] - oldJointPos[axis]) /
02563 emcmotConfig->servoCycleTime;
02564
02565
02566 if (GET_AXIS_ACTIVE_FLAG(axis)) {
02567 #ifdef STEPPER_MOTORS
02568
02569
02570
02571
02572
02573
02574
02575 if (jointPos[axis] - oldJointPos[axis] > 0.0) {
02576 oldbcomp = bcomp[axis];
02577 bcomp[axis] = + emcmotConfig->pid[axis].backlash / 2.0;
02578 if (bcompdir[axis] != + 1) {
02579 bac_done[axis] = 0;
02580 bac_di[axis] = bcompincr[axis];
02581 bac_d[axis] = 0;
02582 bac_D[axis] = bcomp[axis] - oldbcomp;
02583 bac_halfD[axis] = 0.5 * bac_D[axis];
02584 bac_incrincr[axis] = emcmotStatus->acc *
02585 emcmotConfig->servoCycleTime * emcmotConfig->servoCycleTime;
02586 bac_incr[axis] = - 0.5 * bac_incrincr[axis];
02587 bcompdir[axis] = + 1;
02588 }
02589 }
02590 else if (jointPos[axis] - oldJointPos[axis] < 0.0) {
02591 oldbcomp = bcomp[axis];
02592 bcomp[axis] = - emcmotConfig->pid[axis].backlash / 2.0;
02593 if (bcompdir[axis] != - 1) {
02594 bac_done[axis] = 0;
02595 bac_di[axis] = bcompincr[axis];
02596 bac_d[axis] = 0;
02597 bac_D[axis] = bcomp[axis] - oldbcomp;
02598 bac_halfD[axis] = 0.5 * bac_D[axis];
02599 bac_incrincr[axis] = emcmotStatus->acc *
02600 emcmotConfig->servoCycleTime * emcmotConfig->servoCycleTime;
02601 bac_incr[axis] = - 0.5 * bac_incrincr[axis];
02602 bcompdir[axis] = - 1;
02603 }
02604 }
02605
02606
02607
02608 if (! bac_done[axis]) {
02609 if (bac_D[axis] > 0.0) {
02610 bcompincr[axis] = bac_di[axis] + bac_d[axis];
02611 if (bac_d[axis] < bac_halfD[axis]) {
02612 bac_incr[axis] += bac_incrincr[axis];
02613 bac_d[axis] += bac_incr[axis];
02614 }
02615 else if (bac_d[axis] < bac_D[axis]) {
02616 bac_incr[axis] -= bac_incrincr[axis];
02617 bac_d[axis] += bac_incr[axis];
02618 }
02619 if (bac_d[axis] >= bac_D[axis] || bac_incr[axis] <= 0.0) {
02620 bac_done[axis] = 1;
02621 }
02622 }
02623 else {
02624 bcompincr[axis] = bac_di[axis] + bac_d[axis];
02625 if (bac_d[axis] > bac_halfD[axis]) {
02626 bac_incr[axis] += bac_incrincr[axis];
02627 bac_d[axis] -= bac_incr[axis];
02628 }
02629 else if (bac_d[axis] > bac_D[axis]) {
02630 bac_incr[axis] -= bac_incrincr[axis];
02631 bac_d[axis] -= bac_incr[axis];
02632 }
02633 if (bac_d[axis] <= bac_D[axis] || bac_incr[axis] <= 0.0) {
02634 bac_done[axis] = 1;
02635 }
02636 }
02637 }
02638
02639
02640
02641 dsteps = (jointPos[axis] + bcompincr[axis]) *
02642 smStepsPerUnit[axis] + emcmotStatus->inputOffset[axis];
02643
02644 if (dsteps < 0.0) {
02645 smSteps[axis] = (int) (dsteps - 0.5);
02646 }
02647 else {
02648 smSteps[axis] = (int) (dsteps + 0.5);
02649 }
02650
02651
02652 smNewCycle[axis] = 1;
02653 #else
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666
02667
02668 emcmotStatus->output[axis] =
02669 pidRunCycle(&emcmotConfig->pid[axis],
02670 emcmotStatus->input[axis],
02671 jointPos[axis]);
02672 #endif
02673
02674
02675
02676
02677 thisFerror[axis] = jointPos[axis] - emcmotStatus->input[axis];
02678 emcmotDebug->ferrorCurrent[axis] = thisFerror[axis];
02679 magFerror = fabs(thisFerror[axis]);
02680
02681
02682 if (emcmotDebug->ferrorHighMark[axis] < magFerror) {
02683 emcmotDebug->ferrorHighMark[axis] = magFerror;
02684 }
02685
02686
02687 limitFerror = emcmotConfig->maxFerror[axis] /
02688 emcmotConfig->limitVel *
02689 jointVel[axis];
02690 if (limitFerror < emcmotConfig->minFerror[axis]) {
02691 limitFerror = emcmotConfig->minFerror[axis];
02692 }
02693
02694
02695 if (magFerror > limitFerror) {
02696
02697 SET_AXIS_ERROR_FLAG(axis, 1);
02698 SET_AXIS_FERROR_FLAG(axis, 1);
02699 if (enabling) {
02700
02701 reportError("Axis %d following error", axis);
02702 }
02703 enabling = 0;
02704 }
02705 else {
02706 SET_AXIS_FERROR_FLAG(axis, 0);
02707 }
02708 }
02709 else {
02710
02711
02712 }
02713
02714 #ifndef STEPPER_MOTORS
02715
02716
02717
02718
02719
02720
02721
02722 if (emcmotStatus->output[axis] < emcmotConfig->minOutput[axis]) {
02723 emcmotStatus->output[axis] = emcmotConfig->minOutput[axis];
02724 }
02725 else if (emcmotStatus->output[axis] > emcmotConfig->maxOutput[axis]) {
02726 emcmotStatus->output[axis] = emcmotConfig->maxOutput[axis];
02727 }
02728 #endif
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742
02743 if (waitingForLatch[axis]) {
02744 if (GET_AXIS_HOME_SWITCH_FLAG(axis) ||
02745 GET_AXIS_PHL_FLAG(axis) ||
02746 GET_AXIS_NHL_FLAG(axis)) {
02747
02748 #ifdef STEPPER_MOTORS
02749
02750 latchFlag[axis] = 1;
02751 #else
02752 extEncoderResetIndex(axis);
02753 extEncoderReadLatch(axis, &latchFlag[axis]);
02754 #endif
02755 if (latchFlag[axis]) {
02756
02757 saveLatch[axis] = rawInput[axis];
02758 waitingForLatch[axis] = 0;
02759
02760
02761 finalHome[axis] = 0;
02762 tpAbort(&freeAxis[axis]);
02763 }
02764 }
02765 }
02766 }
02767 }
02768 else {
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02781 coarseJointPos[axis] = emcmotStatus->input[axis];
02782 jointPos[axis] = coarseJointPos[axis];
02783 }
02784
02785
02786
02787
02788 if (--interpolationCounter <= 0) {
02789 if (! EMCMOT_NO_FORWARD_KINEMATICS) {
02790
02791 if (allHomed ||
02792 kinType == KINEMATICS_IDENTITY) {
02793 kinematicsForward(emcmotStatus->input, &emcmotStatus->actualPos, &fflags, &iflags);
02794 }
02795 emcmotStatus->pos = emcmotStatus->actualPos;
02796 }
02797
02798
02799 interpolationCounter = emcmotConfig->interpolationRate;
02800 }
02801 }
02802
02803 #ifdef ENABLE_PROBING
02804 extDioRead(emcmotConfig->probeIndex, &emcmotStatus->probeval);
02805 if (emcmotStatus->probing && emcmotStatus->probeTripped) {
02806 tpClear(&queue);
02807 emcmotStatus->probing = 0;
02808 }
02809 else if (emcmotStatus->probing && GET_MOTION_INPOS_FLAG() &&
02810 tpQueueDepth(&queue) == 0) {
02811 emcmotStatus->probing = 0;
02812 }
02813 else if (emcmotStatus->probing) {
02814 if (emcmotStatus->probeval == emcmotConfig->probePolarity) {
02815 emcmotStatus->probeTripped = 1;
02816 emcmotStatus->probedPos = emcmotStatus->actualPos;
02817 if (GET_MOTION_COORD_FLAG()) {
02818 tpAbort(&queue);
02819 SET_MOTION_ERROR_FLAG(0);
02820 }
02821 else {
02822
02823 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02824 tpAbort(&freeAxis[axis]);
02825 SET_AXIS_HOMING_FLAG(axis, 0);
02826 SET_AXIS_ERROR_FLAG(axis, 0);
02827 }
02828 }
02829 }
02830 }
02831 #endif
02832
02833 #ifndef STEPPER_MOTORS
02834
02835
02836
02837 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02838 rawOutput[axis] =
02839 (emcmotStatus->output[axis] - emcmotStatus->outputOffset[axis]) *
02840 inverseOutputScale[axis];
02841 }
02842
02843
02844
02845
02846
02847
02848
02849 extDacWriteAll(EMCMOT_MAX_AXIS, rawOutput);
02850 #endif
02851
02852
02853
02854
02855
02856 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02857 emcmotStatus->axisPos[axis] = jointPos[axis];
02858 }
02859
02860
02861 emcmotStatus->heartbeat++;
02862
02863
02864 emcmotStatus->depth = tpQueueDepth(&queue);
02865 emcmotStatus->activeDepth = tpActiveDepth(&queue);
02866 emcmotStatus->id = tpGetExecId(&queue);
02867 emcmotStatus->queueFull = tcqFull(&queue.queue);
02868 SET_MOTION_INPOS_FLAG(0);
02869 if (tpIsDone(&queue)) {
02870 SET_MOTION_INPOS_FLAG(1);
02871 }
02872
02873
02874 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02875 SET_AXIS_INPOS_FLAG(axis, 0);
02876 if (tpIsDone(&freeAxis[axis])) {
02877 SET_AXIS_INPOS_FLAG(axis, 1);
02878 }
02879 else {
02880
02881 if (emcmotStatus->overrideLimits) {
02882 overriding = 1;
02883 }
02884 }
02885 }
02886
02887
02888
02889 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02890 if (! GET_AXIS_INPOS_FLAG(axis)) {
02891 break;
02892 }
02893 }
02894 if (axis == EMCMOT_MAX_AXIS) {
02895
02896 if (overriding) {
02897 overriding = 0;
02898 emcmotStatus->overrideLimits = 0;
02899 }
02900 }
02901
02902
02903
02904 if (stepping && idForStep != emcmotStatus->id) {
02905 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
02906 tpPause(&freeAxis[axis]);
02907 }
02908 tpPause(&queue);
02909 stepping = 0;
02910 emcmotStatus->paused = 1;
02911 }
02912
02913
02914 end = etime();
02915 delta = end - start;
02916 emcmotStatus->computeTime = delta;
02917 if (2 == whichCycle) {
02918
02919 mmxavgAdd(&emcmotDebug->tMmxavg, delta);
02920 emcmotDebug->tMin = mmxavgMin(&emcmotDebug->tMmxavg);
02921 emcmotDebug->tMax = mmxavgMax(&emcmotDebug->tMmxavg);
02922 emcmotDebug->tAvg = mmxavgAvg(&emcmotDebug->tMmxavg);
02923 }
02924 else if (1 == whichCycle) {
02925
02926 mmxavgAdd(&emcmotDebug->sMmxavg, delta);
02927 emcmotDebug->sMin = mmxavgMin(&emcmotDebug->sMmxavg);
02928 emcmotDebug->sMax = mmxavgMax(&emcmotDebug->sMmxavg);
02929 emcmotDebug->sAvg = mmxavgAvg(&emcmotDebug->sMmxavg);
02930 }
02931 else {
02932
02933 mmxavgAdd(&emcmotDebug->nMmxavg, delta);
02934 emcmotDebug->nMin = mmxavgMin(&emcmotDebug->nMmxavg);
02935 emcmotDebug->nMax = mmxavgMax(&emcmotDebug->nMmxavg);
02936 emcmotDebug->nAvg = mmxavgAvg(&emcmotDebug->nMmxavg);
02937 }
02938
02939
02940 logIt = 0;
02941 if (emcmotStatus->logStarted &&
02942 emcmotStatus->logSkip >= 0) {
02943
02944
02945 ls.type = emcmotStatus->logType;
02946
02947
02948 switch (ls.type) {
02949
02950 case EMCMOT_LOG_TYPE_AXIS_POS:
02951 if (logSkip-- <= 0) {
02952 ls.item.axisPos.time = end;
02953 ls.item.axisPos.input = emcmotStatus->input[loggingAxis];
02954 ls.item.axisPos.output = jointPos[loggingAxis];
02955 logSkip = emcmotStatus->logSkip;
02956 logIt = 1;
02957 }
02958 break;
02959
02960 case EMCMOT_LOG_TYPE_ALL_INPOS:
02961 if (logSkip-- <= 0) {
02962 ls.item.allInpos.time = end;
02963 for (axis = 0;
02964 axis < EMCMOT_LOG_NUM_AXES &&
02965 axis < EMCMOT_MAX_AXIS;
02966 axis++) {
02967 ls.item.allInpos.input[axis] = emcmotStatus->input[axis];
02968 }
02969 logSkip = emcmotStatus->logSkip;
02970 logIt = 1;
02971 }
02972 break;
02973
02974 case EMCMOT_LOG_TYPE_ALL_OUTPOS:
02975 if (logSkip-- <= 0) {
02976 ls.item.allOutpos.time = end;
02977 for (axis = 0;
02978 axis < EMCMOT_LOG_NUM_AXES &&
02979 axis < EMCMOT_MAX_AXIS;
02980 axis++) {
02981 ls.item.allOutpos.output[axis] = jointPos[axis];
02982 }
02983 logSkip = emcmotStatus->logSkip;
02984 logIt = 1;
02985 }
02986 break;
02987
02988 case EMCMOT_LOG_TYPE_AXIS_VEL:
02989 if (logSkip-- <= 0) {
02990 ls.item.axisVel.time = end;
02991 ls.item.axisVel.cmdVel = jointPos[loggingAxis] -
02992 oldJointPos[loggingAxis];
02993 ls.item.axisVel.actVel = emcmotStatus->input[loggingAxis] -
02994 oldInput[loggingAxis];
02995 logSkip = emcmotStatus->logSkip;
02996 logIt = 1;
02997 }
02998 break;
02999
03000 case EMCMOT_LOG_TYPE_ALL_FERROR:
03001 if (logSkip-- <= 0) {
03002 ls.item.allFerror.time = end;
03003 for (axis = 0;
03004 axis < EMCMOT_LOG_NUM_AXES &&
03005 axis < EMCMOT_MAX_AXIS;
03006 axis++) {
03007 ls.item.allFerror.ferror[axis] = thisFerror[axis];
03008 }
03009 logSkip = emcmotStatus->logSkip;
03010 logIt = 1;
03011 }
03012 break;
03013
03014 case EMCMOT_LOG_TYPE_POS_VOLTAGE:
03015
03016 if (emcmotLog->howmany >= emcmotStatus->logSize) {
03017 emcmotStatus->output[loggingAxis] = 0.0;
03018 emcmotStatus->logStarted = 0;
03019 logIt = 0;
03020 break;
03021 }
03022 if (logSkip-- <= 0) {
03023 ls.item.posVoltage.time = end;
03024 for (axis = 0;
03025 axis < EMCMOT_LOG_NUM_AXES &&
03026 axis < EMCMOT_MAX_AXIS;
03027 axis++) {
03028 ls.item.posVoltage.pos = emcmotStatus->input[loggingAxis];
03029 ls.item.posVoltage.voltage = rawOutput[loggingAxis];
03030 }
03031 logSkip = emcmotStatus->logSkip;
03032 logIt = 1;
03033 }
03034 break;
03035
03036 default:
03037 break;
03038 }
03039
03040
03041 #if defined (rtlinux) && defined (RT_FIFO)
03042 if (logIt) {
03043 rtf_put(EMCMOT_LOG_RTF, &ls, sizeof(EMCMOT_LOG_STRUCT));
03044
03045 logIt = 0;
03046 }
03047 #else
03048 if (logIt) {
03049 emcmotLogAdd(emcmotLog, ls);
03050 emcmotStatus->logPoints = emcmotLog->howmany;
03051 logIt = 0;
03052 }
03053 #endif
03054 }
03055
03056
03057 emcmotStatus->tail = emcmotStatus->head;
03058 emcmotDebug->tail = emcmotDebug->head;
03059 emcmotConfig->tail = emcmotConfig->head;
03060
03061
03062
03063 #if defined (rtlinux) && defined (RT_FIFO)
03064
03065 rtf_put(EMCMOT_STATUS_RTF, &emcmotStatusBuffer, sizeof(EMCMOT_STATUS));
03066
03067 #endif
03068
03069 #ifdef rtlinux
03070
03071 #ifdef USE_RTL2
03072 pthread_wait_np();
03073 #else
03074 rt_task_wait();
03075 #endif
03076 }
03077 #endif
03078 #ifdef USE_RTL2
03079 return(NULL);
03080 #endif
03081 }
03082
03083 #ifdef STEPPER_MOTORS
03084
03085
03086
03087
03088
03089
03090
03091
03092
03093
03094
03095
03096
03097
03098
03099
03100
03101
03102
03103
03104
03105
03106 #define _TESTING
03107 #ifdef USE_RTL2
03108 static void *smController(void *arg)
03109 #else
03110 static void smController(int arg)
03111 #endif
03112 {
03113 static unsigned char oldSmLoByte = 0, oldSmHiByte = 0;
03114 static int smCount[EMCMOT_MAX_AXIS];
03115 static int up[EMCMOT_MAX_AXIS];
03116 static int down[EMCMOT_MAX_AXIS];
03117 static int direction[EMCMOT_MAX_AXIS];
03118 #ifdef TESTING
03119 static char toggle = 0;
03120 #endif
03121 int axis;
03122 unsigned char smLoByte = 0, smHiByte = 0;
03123 int delta;
03124 int period;
03125
03126 #ifndef STANDALONE
03127 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
03128 smCount[axis] = 0;
03129 up[axis] = 0;
03130 down[axis] = 0;
03131 direction[axis] = 1;
03132 }
03133
03134 for (;;) {
03135 #endif
03136 smLoByte = oldSmLoByte;
03137 smHiByte = oldSmHiByte;
03138
03139 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
03140
03141 if (smNewCycle[axis]) {
03142 smCount[axis] = smCyclesPerAxis;
03143 smNewCycle[axis] = 0;
03144 }
03145
03146 if (up[axis] > 0) {
03147 up[axis]--;
03148 if (direction[axis]) {
03149 smLoByte |= (0x01 << (axis << 1));
03150 smLoByte |= (0x02 << (axis << 1));
03151 }
03152 else {
03153 smLoByte &= ~(0x01 << (axis << 1));
03154 smLoByte |= (0x02 << (axis << 1));
03155 }
03156 }
03157 else if (down[axis] > 0) {
03158 down[axis]--;
03159 smLoByte &= ~(0x02 << (axis << 1));
03160 }
03161 else {
03162 delta = smSteps[axis] - emcmotDebug->stepperCount[axis];
03163 if (delta > 0) {
03164 direction[axis] = 1;
03165 period = smCount[axis] / +delta;
03166 up[axis] = period / 2;
03167 if (up[axis] <= 0) up[axis] = 1;
03168 down[axis] = period - up[axis];
03169 if (down[axis] <= 0) down[axis] = 1;
03170 smLoByte |= (0x01 << (axis << 1));
03171 smLoByte |= (0x02 << (axis << 1));
03172 emcmotDebug->stepperCount[axis]++;
03173 up[axis]--;
03174 }
03175 else if (delta < 0) {
03176 direction[axis] = 0;
03177 period = smCount[axis] / -delta;
03178 up[axis] = period / 2;
03179 if (up[axis] <= 0) up[axis] = 1;
03180 down[axis] = period - up[axis];
03181 if (down[axis] <= 0) down[axis] = 1;
03182 smLoByte &= ~(0x01 << (axis << 1));
03183 smLoByte |= (0x02 << (axis << 1));
03184 emcmotDebug->stepperCount[axis]--;
03185 up[axis]--;
03186 }
03187 else {
03188
03189 smLoByte &= ~(0x02 << (axis << 1));
03190 }
03191 }
03192
03193 smCount[axis]--;
03194 }
03195
03196 #ifndef STANDALONE
03197 #ifdef TESTING
03198
03199 if (toggle) {
03200 smLoByte |= 0x0C;
03201 }
03202 else {
03203 smLoByte &= ~0x0C;
03204 }
03205 toggle = ! toggle;
03206 #endif
03207
03208 if (smLoByte != oldSmLoByte) {
03209 pptDioByteWrite(0, smLoByte);
03210 oldSmLoByte = smLoByte;
03211 }
03212 if (smHiByte != oldSmHiByte) {
03213 pptDioByteWrite(1, smHiByte);
03214 oldSmHiByte = smHiByte;
03215 }
03216 #else
03217 pptDioByteWrite(0, smLoByte);
03218 #endif
03219
03220 #ifndef STANDALONE
03221 #ifdef USE_RTL2
03222 pthread_wait_np();
03223 #else
03224 rt_task_wait();
03225 #endif
03226 }
03227 #endif
03228 #ifdef USE_RTL2
03229 return(NULL);
03230 #endif
03231
03232 }
03233
03234 #endif
03235
03236
03237
03238 #ifndef __GNUC__
03239 #ifndef __attribute__
03240 #define __attribute__(x)
03241 #endif
03242 #endif
03243
03244 static int __attribute__((unused)) PERIOD = 1;
03245
03246
03247
03248 static int __attribute__((unused)) STEPPING_TYPE = 0;
03249
03250 #if defined(rtlinux2)
03251
03252 MODULE_PARM(PERIOD, "i");
03253 MODULE_PARM(SHMEM_BASE_ADDRESS, "l");
03254 MODULE_PARM(STG_BASE_ADDRESS, "h");
03255 MODULE_PARM(PARPORT_IO_ADDRESS, "l");
03256 MODULE_PARM(EMCMOT_NO_FORWARD_KINEMATICS, "i");
03257 MODULE_PARM(STEPPING_TYPE, "i");
03258 #endif
03259
03260 int init_module(void)
03261 {
03262 int axis;
03263 int t;
03264 #ifdef rtlinux
03265 #ifdef USE_RTL2
03266 hrtime_t now;
03267 pthread_attr_t attr;
03268 struct sched_param sched_param;
03269 clockid_t local_clock;
03270 #else
03271 RTIME now;
03272 #endif
03273 #endif
03274 PID_STRUCT pid;
03275
03276 #ifdef rtlinux
03277
03278 #ifdef RT_FIFO
03279 rtf_create(EMCMOT_COMMAND_RTF, sizeof(EMCMOT_COMMAND) + 1);
03280 rtf_create(EMCMOT_STATUS_RTF, sizeof(EMCMOT_STATUS) + 1);
03281 rtf_create(EMCMOT_ERROR_RTF, EMCMOT_ERROR_NUM * EMCMOT_ERROR_LEN + 1);
03282
03283
03284
03285 emcmotCommand = &emcmotCommandBuffer;
03286 emcmotStatus = &emcmotStatusBuffer;
03287 emcmotConfig = &emcmotConfigBuffer;
03288 emcmotDebug = &emcmotDebugBuffer;
03289
03290 #else
03291
03292
03293 #ifdef USE_RTL2
03294
03295 printk(KERN_INFO "calling mbuff_alloc(%s,%d)\n",
03296 "emcmotStruct",
03297 (int) sizeof(EMCMOT_STRUCT));
03298 emcmotStruct = (EMCMOT_STRUCT *) mbuff_alloc("emcmotStruct",sizeof(EMCMOT_STRUCT));
03299 printk(KERN_INFO "mbuff_alloc returned %d\n",((int) emcmotStruct));
03300
03301 #else
03302 #ifdef rtlinux2
03303
03304 emcmotStruct = (EMCMOT_STRUCT *) ioremap(SHMEM_BASE_ADDRESS, sizeof(EMCMOT_STRUCT));
03305
03306 #else
03307
03308 emcmotStruct = (EMCMOT_STRUCT *) vremap(SHMEM_BASE_ADDRESS, sizeof(EMCMOT_STRUCT));
03309 #endif
03310 #endif
03311
03312 #endif
03313
03314 #else
03315
03316 shmem = rcs_shm_open(SHMEM_KEY, sizeof(EMCMOT_STRUCT), 1, 0666);
03317 if (NULL == shmem ||
03318 NULL == shmem->addr)
03319 {
03320 diagnostics("can't get shared memory\n");
03321 return -1;
03322 }
03323
03324 memset(shmem->addr, 0, sizeof(EMCMOT_STRUCT));
03325
03326 emcmotStruct = (EMCMOT_STRUCT *) shmem->addr;
03327
03328 #endif
03329
03330 #ifndef RT_FIFO
03331
03332 emcmotCommand = (EMCMOT_COMMAND *) &emcmotStruct->command;
03333 emcmotStatus = (EMCMOT_STATUS *) &emcmotStruct->status;
03334 emcmotConfig = (EMCMOT_CONFIG *) &emcmotStruct->config;
03335 emcmotDebug = (EMCMOT_DEBUG *) &emcmotStruct->debug;
03336 emcmotError = (EMCMOT_ERROR *) &emcmotStruct->error;
03337 emcmotLog = (EMCMOT_LOG *) &emcmotStruct->log;
03338 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
03339 emcmotComp[axis] = (EMCMOT_COMP *) &emcmotStruct->comp[axis];
03340 }
03341
03342
03343 for (t = 0; t < sizeof(EMCMOT_STRUCT); t++) {
03344 ((char *) emcmotStruct)[t] = 0;
03345 }
03346 #endif
03347
03348
03349 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
03350 maxLimitSwitchCount[axis] = 0;
03351 minLimitSwitchCount[axis] = 0;
03352 ampFaultCount[axis] = 0;
03353 #ifdef STEPPER_MOTORS
03354 smStepsPerUnit[axis] = INPUT_SCALE;
03355 smMagUnitsPerStep[axis] = fabs(1.0 / INPUT_SCALE);
03356 emcmotDebug->stepperCount[axis] = 0;
03357 smNewCycle[axis] = 1;
03358 #endif
03359 }
03360
03361 #ifndef RT_FIFO
03362
03363 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
03364 emcmotComp[axis]->total = 0;
03365 emcmotComp[axis]->alter = 0.0;
03366
03367
03368 }
03369
03370
03371 emcmotErrorInit(emcmotError);
03372 #endif
03373
03374
03375 emcmotCommand->head = 0;
03376 emcmotCommand->command = 0;
03377 emcmotCommand->commandNum = 0;
03378 emcmotCommand->tail = 0;
03379
03380
03381
03382 emcmotStatus->head = 0;
03383 emcmotConfig->head = 0;
03384 emcmotDebug->head = 0;
03385
03386 emcmotStatus->motionFlag = 0;
03387 SET_MOTION_ERROR_FLAG(0);
03388 SET_MOTION_COORD_FLAG(0);
03389 emcmotDebug->split = 0;
03390 emcmotStatus->commandEcho = 0;
03391 emcmotStatus->commandNumEcho = 0;
03392 emcmotStatus->commandStatus = 0;
03393 emcmotStatus->heartbeat = 0;
03394 emcmotStatus->computeTime = 0.0;
03395 emcmotConfig->numAxes = EMCMOT_MAX_AXIS;
03396 emcmotConfig->trajCycleTime = TRAJ_CYCLE_TIME;
03397 emcmotConfig->servoCycleTime = SERVO_CYCLE_TIME;
03398 emcmotStatus->pos.tran.x = 0.0;
03399 emcmotStatus->pos.tran.y = 0.0;
03400 emcmotStatus->pos.tran.z = 0.0;
03401 emcmotStatus->actualPos.tran.x = 0.0;
03402 emcmotStatus->actualPos.tran.y = 0.0;
03403 emcmotStatus->actualPos.tran.z = 0.0;
03404 emcmotStatus->vel = VELOCITY;
03405 emcmotConfig->limitVel = VELOCITY;
03406 emcmotStatus->acc = ACCELERATION;
03407 emcmotStatus->qVscale = 1.0;
03408 emcmotStatus->id = 0;
03409 emcmotStatus->depth = 0;
03410 emcmotStatus->activeDepth = 0;
03411 emcmotStatus->paused = 0;
03412 emcmotStatus->overrideLimits = 0;
03413 SET_MOTION_INPOS_FLAG(1);
03414 emcmotStatus->logOpen = 0;
03415 emcmotStatus->logStarted = 0;
03416 emcmotStatus->logSize = 0;
03417 emcmotStatus->logSkip = 0;
03418 emcmotStatus->logPoints = 0;
03419 SET_MOTION_ENABLE_FLAG(0);
03420
03421 oldPos = emcmotStatus->pos;
03422 oldVel.tran.x = 0.0;
03423 oldVel.tran.y = 0.0;
03424 oldVel.tran.z = 0.0;
03425
03426 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
03427 emcmotConfig->homingVel[axis] = VELOCITY;
03428 emcmotConfig->homeOffset[axis] = 0.0;
03429 emcmotStatus->axisFlag[axis] = 0;
03430 emcmotConfig->maxLimit[axis] = MAX_LIMIT;
03431 emcmotConfig->minLimit[axis] = MIN_LIMIT;
03432 emcmotConfig->maxOutput[axis] = MAX_OUTPUT;
03433 emcmotConfig->minOutput[axis] = MIN_OUTPUT;
03434 emcmotConfig->minFerror[axis] = 0.0;
03435 emcmotConfig->maxFerror[axis] = MAX_FERROR;
03436 emcmotDebug->ferrorCurrent[axis] = 0.0;
03437 emcmotDebug->ferrorHighMark[axis] = 0.0;
03438 emcmotStatus->outputScale[axis] = OUTPUT_SCALE;
03439 emcmotStatus->outputOffset[axis] = OUTPUT_OFFSET;
03440 emcmotStatus->inputScale[axis] = INPUT_SCALE;
03441 inverseInputScale[axis] = 1.0 / INPUT_SCALE;
03442 emcmotStatus->inputOffset[axis] = INPUT_OFFSET;
03443 inverseOutputScale[axis] = 1.0 / OUTPUT_SCALE;
03444 emcmotStatus->axVscale[axis] = 1.0;
03445 SET_AXIS_ENABLE_FLAG(axis, 0);
03446 SET_AXIS_ACTIVE_FLAG(axis, 0);
03447
03448 SET_AXIS_NSL_FLAG(axis, 0);
03449 SET_AXIS_PSL_FLAG(axis, 0);
03450 SET_AXIS_NHL_FLAG(axis, 0);
03451 SET_AXIS_PHL_FLAG(axis, 0);
03452 SET_AXIS_INPOS_FLAG(axis, 1);
03453 SET_AXIS_HOMING_FLAG(axis, 0);
03454 SET_AXIS_HOMED_FLAG(axis, 0);
03455 SET_AXIS_FERROR_FLAG(axis, 0);
03456 SET_AXIS_FAULT_FLAG(axis, 0);
03457 SET_AXIS_ERROR_FLAG(axis, 0);
03458 emcmotConfig->axisPolarity[axis] = (EMCMOT_AXIS_FLAG) 0xFFFFFFFF;
03459
03460 }
03461
03462
03463
03464
03465 mmxavgInit(&emcmotDebug->tMmxavg, emcmotDebug->tMmxavgSpace, MMXAVG_SIZE);
03466 mmxavgInit(&emcmotDebug->sMmxavg, emcmotDebug->sMmxavgSpace, MMXAVG_SIZE);
03467 mmxavgInit(&emcmotDebug->nMmxavg, emcmotDebug->nMmxavgSpace, MMXAVG_SIZE);
03468 emcmotDebug->tMin = 0.0;
03469 emcmotDebug->tMax = 0.0;
03470 emcmotDebug->tAvg = 0.0;
03471 emcmotDebug->sMin = 0.0;
03472 emcmotDebug->sMax = 0.0;
03473 emcmotDebug->sAvg = 0.0;
03474 emcmotDebug->nMin = 0.0;
03475 emcmotDebug->nMax = 0.0;
03476 emcmotDebug->nAvg = 0.0;
03477
03478
03479 if (-1 == tpCreate(&queue, DEFAULT_TC_QUEUE_SIZE, queueTcSpace)) {
03480 diagnostics("can't create motion queue\n");
03481 return -1;
03482 }
03483 tpInit(&queue);
03484 tpSetCycleTime(&queue, emcmotConfig->trajCycleTime);
03485 tpSetPos(&queue, emcmotStatus->pos);
03486 tpSetVmax(&queue, emcmotStatus->vel);
03487 tpSetAmax(&queue, emcmotStatus->acc);
03488
03489
03490 pid.p = P_GAIN;
03491 pid.i = I_GAIN;
03492 pid.d = D_GAIN;
03493 pid.ff0 = FF0_GAIN;
03494 pid.ff1 = FF1_GAIN;
03495 pid.ff2 = FF2_GAIN;
03496 pid.backlash = BACKLASH;
03497 pid.bias = BIAS;
03498 pid.maxError = MAX_ERROR;
03499
03500 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
03501 if (-1 == tpCreate(&freeAxis[axis], FREE_AXIS_QUEUE_SIZE, freeAxisTcSpace[axis])) {
03502 diagnostics("can't create axis queue %d\n", axis);
03503 return -1;
03504 }
03505 tpInit(&freeAxis[axis]);
03506 tpSetCycleTime(&freeAxis[axis], emcmotConfig->trajCycleTime);
03507
03508 tpSetPos(&freeAxis[axis], freePose);
03509 tpSetVmax(&freeAxis[axis], emcmotStatus->vel);
03510 tpSetAmax(&freeAxis[axis], emcmotStatus->acc);
03511 #ifndef STEPPER_MOTORS
03512 pidInit(&emcmotConfig->pid[axis]);
03513 pidSetGains(&emcmotConfig->pid[axis], pid);
03514 #endif
03515 cubicInit(&cubic[axis]);
03516 }
03517
03518
03519
03520 setTrajCycleTime(TRAJ_CYCLE_TIME);
03521 setServoCycleTime(SERVO_CYCLE_TIME);
03522
03523
03524 if (-1 == extMotInit((const char *) 0)) {
03525 diagnostics("can't initialize motion hardware\n");
03526 return -1;
03527 }
03528 if (-1 == extDioInit((const char *) 0)) {
03529 diagnostics("can't initialize DIO hardware\n");
03530 return -1;
03531 }
03532 if (-1 == extAioInit((const char *) 0)) {
03533 diagnostics("can't initialize AIO hardware\n");
03534 return -1;
03535 }
03536
03537
03538 kinType = kinematicsType();
03539
03540 extEncoderSetIndexModel(EXT_ENCODER_INDEX_MODEL_MANUAL);
03541 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
03542 rawInput[axis] = 0.0;
03543 rawOutput[axis] = 0.0;
03544 coarseJointPos[axis] = 0.0;
03545 jointPos[axis] = 0.0;
03546 jointVel[axis] = 0.0;
03547 emcmotStatus->axisPos[axis] = 0.0;
03548 oldJointPos[axis] = 0.0;
03549
03550 waitingForLatch[axis] = 0;
03551 latchFlag[axis] = 0;
03552 saveLatch[axis] = 0.0;
03553
03554 emcmotStatus->input[axis] = 0.0;
03555 oldInput[axis] = 0.0;
03556 emcmotStatus->output[axis] = 0.0;
03557
03558 jointHome[axis] = 0.0;
03559
03560 extAmpEnable(axis,
03561 ! GET_AXIS_ENABLE_POLARITY(axis));
03562 }
03563
03564 emcmotStatus->tail = 0;
03565
03566 #ifdef rtlinux
03567
03568
03569 #ifdef USE_RTL2
03570 local_clock = rtl_getschedclock();
03571
03572 #if 0
03573 if(!rtl_setclockmode(local_clock, RTL_CLOCK_MODE_PERIODIC, 20000))
03574 {
03575 diagnostics("can't set periodic mode\n");
03576 }
03577 #else
03578 rtl_setclockmode(local_clock, RTL_CLOCK_MODE_ONESHOT,0);
03579 #endif
03580
03581 #else // RTL before version 2
03582 #if 0
03583 if (RT_TIME_END == rtl_set_periodic_mode(20)) {
03584 diagnostics("can't set periodic mode\n");
03585 }
03586 #else
03587 rtl_set_oneshot_mode();
03588 #endif
03589
03590 #endif
03591
03592 #ifdef USE_RTL2
03593 pthread_attr_init (&attr);
03594 sched_param.sched_priority = RT_TASK_PRIORITY;
03595 pthread_attr_setschedparam (&attr, &sched_param);
03596 attr.use_fp = 1;
03597 attr.stack_size = RT_TASK_STACK_SIZE;
03598 pthread_create( &emcmotTask, &attr, emcmotController, (void *) 1);
03599
03600
03601 now =gethrtime();
03602
03603 pthread_setfp_np(emcmotTask,1);
03604 pthread_make_periodic_np(emcmotTask,
03605 now + 0.010*HRTICKS_PER_SEC,
03606 (hrtime_t) (HRTICKS_PER_SEC *
03607 emcmotConfig->servoCycleTime));
03608 #else
03609
03610
03611 rt_task_init(&emcmotTask,
03612 emcmotController,
03613 0,
03614 RT_TASK_STACK_SIZE,
03615 RT_TASK_PRIORITY);
03616
03617
03618 rt_task_use_fp(&emcmotTask, 1);
03619
03620
03621 now = rt_get_time();
03622
03623
03624 rt_task_make_periodic(&emcmotTask,
03625 now + SECS_TO_RTIME(0.010),
03626 (RTIME) (RT_TICKS_PER_SEC *
03627 emcmotConfig->servoCycleTime));
03628
03629
03630 #endif
03631
03632
03633
03634 #ifdef STEPPER_MOTORS
03635
03636
03637
03638
03639
03640
03641 smVPmax = VELOCITY * INPUT_SCALE;
03642 smMaxStepsPerUnit = INPUT_SCALE;
03643
03644
03645
03646 smCycleTime = 0.5/smVPmax;
03647 smCyclesPerAxis = (int) (emcmotConfig->servoCycleTime / smCycleTime);
03648
03649
03650 #ifdef USE_RTL2
03651 pthread_attr_init (&attr);
03652 sched_param.sched_priority = SM_TASK_PRIORITY;
03653 pthread_attr_setschedparam (&attr, &sched_param);
03654 attr.use_fp = 1;
03655 attr.stack_size = SM_TASK_STACK_SIZE;
03656 pthread_create( &smTask, &attr, smController, NULL);
03657
03658
03659 now =gethrtime();
03660
03661 pthread_setfp_np(emcmotTask,1);
03662 pthread_make_periodic_np(emcmotTask,
03663 now + 0.010*HRTICKS_PER_SEC,
03664 (hrtime_t) (HRTICKS_PER_SEC *
03665 smCycleTime));
03666
03667 #else
03668
03669
03670 rt_task_init(&smTask,
03671 smController,
03672 0,
03673 SM_TASK_STACK_SIZE,
03674 SM_TASK_PRIORITY);
03675
03676
03677 rt_task_use_fp(&smTask, 1);
03678
03679 rt_task_make_periodic(&smTask,
03680 now + SECS_TO_RTIME(0.010),
03681 ((RTIME) (RT_TICKS_PER_SEC * smCycleTime)));
03682
03683 #endif
03684 #endif
03685
03686
03687 diagnostics("inited emcmot\n");
03688
03689 #endif
03690
03691 #if defined (rtlinux) && defined (RT_FIFO)
03692
03693 rtf_create_handler(EMCMOT_COMMAND_RTF,
03694 emcmotCommandHandler
03695 );
03696
03697 #endif
03698
03699 return 0;
03700 }
03701
03702 void cleanup_module(void)
03703 {
03704 int axis;
03705
03706
03707 tpDelete(&queue);
03708
03709
03710 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) {
03711 extAmpEnable(axis,
03712 ! GET_AXIS_ENABLE_POLARITY(axis));
03713 }
03714
03715
03716 extAioQuit();
03717 extDioQuit();
03718 extMotQuit();
03719
03720 #ifdef rtlinux
03721
03722 #ifdef RT_FIFO
03723 rtf_destroy(EMCMOT_COMMAND_RTF);
03724 rtf_destroy(EMCMOT_STATUS_RTF);
03725 rtf_destroy(EMCMOT_ERROR_RTF);
03726 #endif
03727
03728
03729 #ifdef USE_RTL2
03730 pthread_delete_np(emcmotTask);
03731 #else
03732 rt_task_delete(&emcmotTask);
03733 #endif
03734
03735 #ifdef STEPPER_MOTORS
03736
03737
03738 #ifdef USE_RTL2
03739 pthread_delete_np(smTask);
03740 #else
03741 rt_task_delete(&smTask);
03742 #endif
03743
03744 #endif
03745
03746
03747 #ifdef USE_RTL2
03748 mbuff_free("emcmotStruct",emcmotStruct);
03749 #else
03750 #ifdef rtlinux2
03751 iounmap(emcmotStruct);
03752 #else
03753 vfree(emcmotStruct);
03754 #endif
03755 #endif
03756
03757
03758
03759 diagnostics("exited emcmot\n");
03760 #ifdef STEPPER_MOTORS
03761 diagnostics("sm cycle time %d\n", (int) (smCycleTime * 1000000.0));
03762 diagnostics("sm cycles per axis %d\n", smCyclesPerAxis);
03763 #endif
03764
03765 #else
03766
03767
03768 if (NULL != shmem) {
03769 rcs_shm_close(shmem);
03770 shmem = NULL;
03771 }
03772
03773 #endif
03774 }
03775
03776
03777
03778 #ifndef rtlinux
03779 int emcmot_done = 0;
03780 static void emcmot_quit(int sig)
03781 {
03782 emcmot_done = 1;
03783 }
03784
03785 #ifndef UNDER_CE
03786 #include <signal.h>
03787 #endif
03788
03789 #ifndef UNDER_CE
03790 static int getArgs(int argc, char *argv[])
03791 {
03792 int t;
03793 int len;
03794
03795 for (t = 1; t < argc; t++) {
03796
03797
03798
03799
03800 if (!strcmp(argv[t], "-ini")) {
03801 if (t == argc - 1) {
03802 diagnostics("missing -ini parameter\n");
03803 return -1;
03804 }
03805 else {
03806 strcpy(EMCMOT_INIFILE, argv[t+1]);
03807 t++;
03808 continue;
03809 }
03810 }
03811
03812
03813 len = strlen("SHMEM_BASE_ADDRESS");
03814 if (! strncmp(argv[t], "SHMEM_BASE_ADDRESS", len)) {
03815 if (argv[t][len] != '=' ||
03816 1 != sscanf(&argv[t][len + 1], "%i", &SHMEM_BASE_ADDRESS)) {
03817 diagnostics("syntax: %s SHMEM_BASE_ADDRESS=integer\n", argv[0]);
03818 return -1;
03819 }
03820 else {
03821 continue;
03822 }
03823 }
03824
03825
03826 len = strlen("SHMEM_KEY");
03827 if (! strncmp(argv[t], "SHMEM_KEY", len)) {
03828 if (argv[t][len] != '=' ||
03829 1 != sscanf(&argv[t][len + 1], "%i", &SHMEM_KEY)) {
03830 diagnostics("syntax: %s SHMEM_KEY=integer\n", argv[0]);
03831 return -1;
03832 }
03833 else {
03834 continue;
03835 }
03836 }
03837
03838
03839
03840 if (!strcmp(argv[t], "-noforward")) {
03841 EMCMOT_NO_FORWARD_KINEMATICS = 1;
03842 continue;
03843 }
03844
03845
03846 diagnostics("bad argument to %s: %s\n", argv[0], argv[t]);
03847 return -1;
03848 }
03849
03850 return 0;
03851 }
03852 #endif
03853
03854
03855
03856
03857
03858
03859
03860 #ifndef UNDER_CE
03861 int main(int argc, char *argv[])
03862 #else
03863 int emcmotsim()
03864 #endif
03865 {
03866 double delta;
03867
03868 #ifndef UNDER_CE
03869
03870 signal(SIGINT, emcmot_quit);
03871
03872
03873 if (0 != getArgs(argc, argv)) {
03874 diagnostics("can't init module-- bad arguments\n");
03875 exit(1);
03876 }
03877 #endif
03878
03879
03880 if (-1 == init_module()) {
03881 diagnostics("can't init module-- execution permission problems?\n");
03882 #ifndef UNDER_CE
03883 exit(1);
03884 #else
03885 return 1;
03886 #endif
03887 }
03888
03889 while (! emcmot_done) {
03890 delta = etime();
03891 emcmotController(0);
03892 delta = etime() - delta;
03893 delta = emcmotConfig->servoCycleTime - delta;
03894
03895 if (delta > 0.0) {
03896 esleep(delta);
03897 }
03898 }
03899
03900 cleanup_module();
03901 #ifndef UNDER_CE
03902 exit(0);
03903 #else
03904 return 0;
03905 #endif
03906 }
03907
03908 #endif