#include "posemath.h"
#include "emcpos.h"
#include "cubic.h"
#include "pid.h"
#include "emcmotcfg.h"
#include "emcmotlog.h"
#include "tp.h"
#include "tc.h"
#include "mmxavg.h"
Include dependency graph for emcmot.h:
This graph shows which files directly or indirectly include this file:
Go to the source code of this file.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Definition at line 107 of file emcmot.h. 00107 { 00108 EMCMOT_SET_TRAJ_CYCLE_TIME = 1, /* set the cycle time */ 00109 EMCMOT_SET_SERVO_CYCLE_TIME, /* set the interpolation rate */ 00110 EMCMOT_SET_POSITION_LIMITS, /* set the axis position +/- limits */ 00111 EMCMOT_SET_OUTPUT_LIMITS, /* set the axis output +/- limits */ 00112 EMCMOT_SET_OUTPUT_SCALE, /* scale factor for outputs */ 00113 EMCMOT_SET_INPUT_SCALE, /* scale factor for inputs */ 00114 EMCMOT_SET_MIN_FERROR, /* minimum following error, input units */ 00115 EMCMOT_SET_MAX_FERROR, /* maximum following error, input units */ 00116 EMCMOT_JOG_CONT, /* continuous jog */ 00117 EMCMOT_JOG_INCR, /* incremental jog */ 00118 EMCMOT_JOG_ABS, /* absolute jog */ 00119 EMCMOT_SET_LINE, /* queue up a linear move */ 00120 EMCMOT_SET_CIRCLE, /* queue up a circular move */ 00121 EMCMOT_SET_VEL, /* set the velocity for subsequent moves */ 00122 EMCMOT_SET_VEL_LIMIT, /* set the absolute max vel for all moves */ 00123 EMCMOT_SET_AXIS_VEL_LIMIT, /* set the absolute max vel for each axis */ 00124 EMCMOT_SET_ACC, /* set the acceleration for moves */ 00125 EMCMOT_PAUSE, /* pause motion */ 00126 EMCMOT_RESUME, /* resume motion */ 00127 EMCMOT_STEP, /* resume motion until id encountered */ 00128 EMCMOT_ABORT, /* abort motion */ 00129 EMCMOT_SCALE, /* scale the speed */ 00130 EMCMOT_ENABLE, /* enable servos for active axes */ 00131 EMCMOT_DISABLE, /* disable servos for active axes */ 00132 EMCMOT_SET_PID, /* set PID gains */ 00133 EMCMOT_ENABLE_AMPLIFIER, /* enable amp outputs and dac writes */ 00134 EMCMOT_DISABLE_AMPLIFIER, /* disable amp outputs and dac writes */ 00135 EMCMOT_OPEN_LOG, /* open a log */ 00136 EMCMOT_START_LOG, /* start logging */ 00137 EMCMOT_STOP_LOG, /* stop logging */ 00138 EMCMOT_CLOSE_LOG, /* close log */ 00139 EMCMOT_DAC_OUT, /* write directly to the dacs */ 00140 EMCMOT_HOME, /* home an axis */ 00141 EMCMOT_FREE, /* set mode to free (joint) motion */ 00142 EMCMOT_COORD, /* set mode to coordinated motion */ 00143 EMCMOT_TELEOP, /* set mode to teleop*/ 00144 EMCMOT_ENABLE_WATCHDOG, /* enable watchdog sound, parport */ 00145 EMCMOT_DISABLE_WATCHDOG, /* enable watchdog sound, parport */ 00146 EMCMOT_SET_POLARITY, /* set polarity for axis flags */ 00147 EMCMOT_ACTIVATE_AXIS, /* make axis active */ 00148 EMCMOT_DEACTIVATE_AXIS, /* make axis inactive */ 00149 EMCMOT_SET_TERM_COND, /* set termination condition (stop, blend) */ 00150 EMCMOT_SET_HOMING_VEL, /* set the axis homing speed */ 00151 EMCMOT_SET_NUM_AXES, /* set the number of axes */ 00152 EMCMOT_SET_WORLD_HOME, /* set pose for world home */ 00153 EMCMOT_SET_JOINT_HOME, /* set value for joint homes */ 00154 EMCMOT_SET_HOME_OFFSET, /* where to go after a home */ 00155 EMCMOT_OVERRIDE_LIMITS, /* temporarily ignore limits until jog done */ 00156 EMCMOT_SET_TELEOP_VECTOR, /* Move at a given velocity but in 00157 world cartesian coordinates, not in joint 00158 space like EMCMOT_JOG_* */ 00159 #ifdef ENABLE_PROBING 00160 EMCMOT_SET_PROBE_INDEX, /* set which wire the probe signal is on. */ 00161 EMCMOT_SET_PROBE_POLARITY, /* probe tripped on 0 to 1 transition or on 00162 1 to 0 transition. */ 00163 EMCMOT_CLEAR_PROBE_FLAGS, /* clears probeTripped flag */ 00164 EMCMOT_PROBE, /* go towards a position, stop if the probe 00165 is tripped, and record the position where 00166 the probe tripped */ 00167 EMCMOT_SET_DEBUG, /* sets the debug level */ 00168 EMCMOT_SET_AOUT, /* sets an analog motion point for next move */ 00169 EMCMOT_SET_DOUT /* sets a digital motion point for next move */ 00170 #endif 00171 00172 }; |
|
Definition at line 348 of file emcmot.h. 00348 { 00349 KINEMATICS_IDENTITY = 1, /* forward=inverse, both well-behaved */ 00350 KINEMATICS_FORWARD_ONLY, /* forward but no inverse */ 00351 KINEMATICS_INVERSE_ONLY, /* inverse but no forward */ 00352 KINEMATICS_BOTH /* forward and inverse both */ 00353 } KINEMATICS_TYPE; |
|
Definition at line 2904 of file emcsegmot.c. 02905 { 02906 int axis; 02907 02908 /* release traj planner space */ 02909 #if !defined(rtlinux) 02910 free(sqMemPool); 02911 #endif 02912 sqTrashQueue(&queue); 02913 02914 /* release axis planner spaces */ 02915 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) 02916 { 02917 tpDelete(&freeAxis[axis]); 02918 } 02919 02920 /* disable amps */ 02921 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) 02922 { 02923 extAmpEnable(axis, 02924 ! GET_AXIS_ENABLE_POLARITY(axis)); 02925 } 02926 02927 /* quit board */ 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 /* delete control task */ 02941 rt_task_delete(&emcmotTask); 02942 02943 /* FIXME */ 02944 diagnostics("exited emcmot\n"); 02945 02946 #ifdef STEPPER_MOTORS 02947 02948 /* delete stepper motor task */ 02949 rt_task_delete(&smTask); 02950 02951 #endif 02952 02953 #else 02954 02955 /* detach from shmem */ 02956 if (NULL != shmem) 02957 { 02958 rcs_shm_close(shmem); 02959 shmem = NULL; 02960 } 02961 02962 #endif 02963 } |
|
Definition at line 77 of file emcmotutil.c. 00078 { 00079 char *p1; 00080 const char *p2; 00081 int i; 00082 if (errlog == 0 || 00083 errlog->num == 0) { 00084 /* empty */ 00085 return -1; 00086 } 00087 00088 errlog->head++; 00089 00090 // strncpy(error, errlog->error[errlog->start], EMCMOT_ERROR_LEN); 00091 // replaced strncpy with manual copy 00092 p1=error; 00093 p2=errlog->error[errlog->start]; 00094 i=0; 00095 while(*p2 && i < EMCMOT_ERROR_LEN) 00096 { 00097 *p1 = *p2; 00098 p1++; 00099 p2++; 00100 i++; 00101 } 00102 *p1=0; 00103 00104 00105 errlog->start = (errlog->start + 1) % EMCMOT_ERROR_NUM; 00106 errlog->num--; 00107 00108 errlog->tail = errlog->head; 00109 00110 return 0; 00111 } |
|
Referenced by init_module().
|
|
Definition at line 41 of file emcmotutil.c. 00042 { 00043 char *p1; 00044 const char *p2; 00045 int i; 00046 00047 if (errlog == 0 || 00048 errlog->num == EMCMOT_ERROR_NUM) { 00049 /* full */ 00050 return -1; 00051 } 00052 00053 errlog->head++; 00054 00055 // strncpy(errlog->error[errlog->end], error, EMCMOT_ERROR_LEN); 00056 // replaced strncpy with manual copy 00057 p1=errlog->error[errlog->end]; 00058 p2=error; 00059 i=0; 00060 while(*p2 && i < EMCMOT_ERROR_LEN) 00061 { 00062 *p1 = *p2; 00063 p1++; 00064 p2++; 00065 i++; 00066 } 00067 *p1=0; 00068 00069 errlog->end = (errlog->end + 1) % EMCMOT_ERROR_NUM; 00070 errlog->num++; 00071 00072 errlog->tail = errlog->head; 00073 00074 return 0; 00075 } |
|
Definition at line 2570 of file emcsegmot.c. 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 /* log is created, deleted dynamically */ 02586 02587 /* fifo puts and gets work on buffer structs, so point to these */ 02588 emcmotCommand = &emcmotCommandBuffer; 02589 emcmotStatus = &emcmotStatusBuffer; 02590 02591 #else /* not RT_FIFO */ 02592 /* set upper memory pointers */ 02593 emcmotStruct = (EMCMOT_STRUCT *) SHMEM_BASE_ADDRESS; 02594 02595 #endif /* else not RT_FIFO */ 02596 02597 #else /* not rtlinux */ 02598 /* get command shmem */ 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 /* map shmem area into local address space */ 02609 emcmotStruct = (EMCMOT_STRUCT *) shmem->addr; 02610 02611 #endif /* else not rtlinux */ 02612 02613 #ifndef RT_FIFO 02614 /* we'll reference emcmotStruct directly */ 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 /* zero shared memory */ 02621 for (t = 0; t < sizeof(EMCMOT_STRUCT); t++) 02622 { 02623 ((char *) emcmotStruct)[t] = 0; 02624 } 02625 #endif /* not RT_FIFO */ 02626 02627 /* init locals */ 02628 for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++) 02629 { 02630 maxLimitSwitchCount[axis] = 0; 02631 minLimitSwitchCount[axis] = 0; 02632 /* STEPPER MOTORS */ 02633 smStepsPerUnit[axis] = 1.0; 02634 smStepsAccum[axis] = 0; 02635 smClkPhase[axis] = 0; 02636 /* END STEPPER MOTORS */ 02637 } 02638 02639 #ifndef RT_FIFO 02640 /* init error struct */ 02641 emcmotErrorInit(emcmotError); 02642 #endif /* not RT_FIFO */ 02643 02644 /* init command struct */ 02645 emcmotCommand->head = 0; 02646 emcmotCommand->command = 0; 02647 emcmotCommand->commandNum = 0; 02648 emcmotCommand->tail = 0; 02649 02650 /* init status struct */ 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); /* default is use it */ 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 /* will read encoders directly, so don't set them here */ 02722 } 02723 02724 /* FIXME-- add emcmotError */ 02725 02726 /* init min-max-avg stats */ 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 /* init motion queue */ 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 /* FIX ME ^^^^ the feed and the absolute maximum velocity 02761 are set the same number */ 02762 02763 sqSetMaxAcc(&queue, emcmotStatus->acc); 02764 sqSetMaxFeedOverride(&queue, 1.0 ); 02765 02766 /* init the axis components */ 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 /* init the time and rate using functions to affect traj, the 02795 pids, and the cubics properly, since they're coupled */ 02796 setTrajCycleTime(TRAJ_CYCLE_TIME); 02797 setServoCycleTime(SERVO_CYCLE_TIME); 02798 02799 /* init board */ 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 /* get current time as base for starting tasks */ 02844 now = rt_get_time(); 02845 02846 /* init control task */ 02847 rt_task_init(&emcmotTask, /* RT_TASK * */ 02848 emcmotController, /* task code */ 02849 0, /* startup arg to task code */ 02850 RT_TASK_STACK_SIZE, /* task stack size */ 02851 RT_TASK_PRIORITY); /* priority */ 02852 02853 /* make sure we save FP context */ 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 /* schedule control task to run */ 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 /* init stepper motor task */ 02870 rt_task_init(&smTask, /* RT_TASK * */ 02871 smController, /* task code */ 02872 0, /* startup arg to task code */ 02873 SM_TASK_STACK_SIZE, /* task stack size */ 02874 SM_TASK_PRIORITY); /* priority */ 02875 02876 /* make sure we save FP context */ 02877 #if defined(rtlinux_09J) || defined(rtlinux_1_0) 02878 rt_task_use_fp(&smTask, 1); 02879 #endif 02880 02881 /* schedule stepper task to run at twice servo (axis) rate */ 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 /* FIXME */ 02890 diagnostics("inited emcmot\n"); 02891 02892 #endif /* rtlinux */ 02893 02894 #if defined (rtlinux) && defined (RT_FIFO) 02895 /* create user process handler on control channel */ 02896 rtf_create_handler(EMCMOT_COMMAND_RTF, /* fifo number */ 02897 emcmotCommandHandler /* control message handler */ 02898 ); 02899 02900 #endif /* rtlinux and RT_FIFO */ 02901 return 0; 02902 } |
|
Definition at line 270 of file genhexkins.c. 00274 { 00275 double InverseJacobian[NUM_STRUTS][NUM_STRUTS]; 00276 double Jacobian[NUM_STRUTS][NUM_STRUTS]; 00277 double velmatrix[6]; 00278 00279 if (0 != JInvMat(pos, InverseJacobian)) { 00280 return -1; 00281 } 00282 if (0 != MatInvert(InverseJacobian, Jacobian)) { 00283 return -1; 00284 } 00285 00286 /* Multiply J[] by jointvels to get vels */ 00287 MatMult(Jacobian, jointvels, velmatrix); 00288 vel->tran.x = velmatrix[0]; 00289 vel->tran.y = velmatrix[1]; 00290 vel->tran.z = velmatrix[2]; 00291 vel->a = velmatrix[3]; 00292 vel->b = velmatrix[4]; 00293 vel->c = velmatrix[5]; 00294 00295 return 0; 00296 } |
|
Definition at line 242 of file genhexkins.c. 00246 { 00247 double InverseJacobian[NUM_STRUTS][NUM_STRUTS]; 00248 double velmatrix[6]; 00249 00250 if (0 != JInvMat(pos, InverseJacobian)) { 00251 return -1; 00252 } 00253 00254 /* Multiply Jinv[] by vel[] to get jointvels */ 00255 velmatrix[0] = vel->tran.x; /* dx/dt */ 00256 velmatrix[1] = vel->tran.y; /* dy/dt */ 00257 velmatrix[2] = vel->tran.z; /* dz/dt */ 00258 velmatrix[3] = vel->a; /* droll/dt */ 00259 velmatrix[4] = vel->b; /* dpitch/dt */ 00260 velmatrix[5] = vel->c; /* dyaw/dt */ 00261 MatMult(InverseJacobian, velmatrix, jointvels); 00262 00263 return 0; 00264 } |
|
Definition at line 304 of file genhexkins.c. 00308 { 00309 PmCartesian aw; 00310 PmCartesian InvKinStrutVect,InvKinStrutVectUnit; 00311 PmCartesian q_trans, RMatrix_a, RMatrix_a_cross_Strut; 00312 00313 double Jacobian[NUM_STRUTS][NUM_STRUTS]; 00314 double InverseJacobian[NUM_STRUTS][NUM_STRUTS]; 00315 double InvKinStrutLength, StrutLengthDiff[NUM_STRUTS]; 00316 double delta[NUM_STRUTS]; 00317 double conv_err = 1.0; 00318 00319 PmRotationMatrix RMatrix; 00320 PmRpy q_RPY; 00321 00322 int iterate = 1; 00323 int i; 00324 int iteration = 0; 00325 int retval = 0; 00326 00327 #define HIGH_CONV_CRITERION (1e-12) 00328 #define MEDIUM_CONV_CRITERION (1e-5) 00329 #define LOW_CONV_CRITERION (1e-3) 00330 #define MEDIUM_CONV_ITERATIONS 50 00331 #define LOW_CONV_ITERATIONS 100 00332 #define FAIL_CONV_ITERATIONS 150 00333 #define LARGE_CONV_ERROR 10000 00334 double conv_criterion = HIGH_CONV_CRITERION; 00335 00336 /* abort on obvious problems, like joints <= 0 */ 00337 /* FIXME-- should check against triangle inequality, so that joints 00338 are never too short to span shared base and platform sides */ 00339 if (joints[0] <= 0.0 || 00340 joints[1] <= 0.0 || 00341 joints[2] <= 0.0 || 00342 joints[3] <= 0.0 || 00343 joints[4] <= 0.0 || 00344 joints[5] <= 0.0) { 00345 return -1; 00346 } 00347 00348 /* assign a,b,c to roll, pitch, yaw angles */ 00349 q_RPY.r = pos->a * PM_PI / 180.0; 00350 q_RPY.p = pos->b * PM_PI / 180.0; 00351 q_RPY.y = pos->c * PM_PI / 180.0; 00352 00353 /* Assign translation values in pos to q_trans */ 00354 q_trans.x = pos->tran.x; 00355 q_trans.y = pos->tran.y; 00356 q_trans.z = pos->tran.z; 00357 00358 /* Enter Newton-Raphson iterative method */ 00359 while (iterate) { 00360 /* check for large error and return error flag if no convergence */ 00361 if ((conv_err > +LARGE_CONV_ERROR) || 00362 (conv_err < -LARGE_CONV_ERROR)) { 00363 /* we can't converge */ 00364 return -2; 00365 }; 00366 00367 iteration++; 00368 00369 #if 0 00370 /* if forward kinematics are having a difficult time converging 00371 ease the restrictions on the convergence criterion */ 00372 if (iteration == MEDIUM_CONV_ITERATIONS) { 00373 conv_criterion = MEDIUM_CONV_CRITERION; 00374 retval = -3; /* this means if we eventually converge, 00375 the result is sloppy */ 00376 } 00377 00378 if (iteration == LOW_CONV_ITERATIONS) { 00379 conv_criterion = LOW_CONV_CRITERION; 00380 retval = -4; /* this means if we eventually converge, 00381 the result is even sloppier */ 00382 } 00383 #endif 00384 00385 /* check iteration to see if the kinematics can reach the 00386 convergence criterion and return error flag if it can't */ 00387 if (iteration > FAIL_CONV_ITERATIONS) { 00388 /* we can't converge */ 00389 return -5; 00390 } 00391 00392 /* Convert q_RPY to Rotation Matrix */ 00393 pmRpyMatConvert(q_RPY, &RMatrix); 00394 00395 /* compute StrutLengthDiff[] by running inverse kins on Cartesian 00396 estimate to get joint estimate, subtract joints to get joint deltas, 00397 and compute inv J while we're at it */ 00398 for (i = 0; i < NUM_STRUTS; i++) { 00399 pmMatCartMult(RMatrix, a[i], &RMatrix_a); 00400 pmCartCartAdd(q_trans, RMatrix_a, &aw); 00401 pmCartCartSub(aw,b[i], &InvKinStrutVect); 00402 if (0 != pmCartUnit(InvKinStrutVect, &InvKinStrutVectUnit)) { 00403 return -1; 00404 } 00405 pmCartMag(InvKinStrutVect, &InvKinStrutLength); 00406 StrutLengthDiff[i] = InvKinStrutLength - joints[i]; 00407 00408 /* Determine RMatrix_a_cross_strut */ 00409 pmCartCartCross(RMatrix_a, InvKinStrutVectUnit, &RMatrix_a_cross_Strut); 00410 00411 /* Build Inverse Jacobian Matrix */ 00412 InverseJacobian[i][0] = InvKinStrutVectUnit.x; 00413 InverseJacobian[i][1] = InvKinStrutVectUnit.y; 00414 InverseJacobian[i][2] = InvKinStrutVectUnit.z; 00415 InverseJacobian[i][3] = RMatrix_a_cross_Strut.x; 00416 InverseJacobian[i][4] = RMatrix_a_cross_Strut.y; 00417 InverseJacobian[i][5] = RMatrix_a_cross_Strut.z; 00418 } 00419 00420 /* invert Inverse Jacobian */ 00421 MatInvert(InverseJacobian, Jacobian); 00422 00423 /* multiply Jacobian by LegLengthDiff */ 00424 MatMult(Jacobian, StrutLengthDiff, delta); 00425 00426 /* subtract delta from last iterations pos values */ 00427 q_trans.x -= delta[0]; 00428 q_trans.y -= delta[1]; 00429 q_trans.z -= delta[2]; 00430 q_RPY.r -= delta[3]; 00431 q_RPY.p -= delta[4]; 00432 q_RPY.y -= delta[5]; 00433 00434 /* determine value of conv_error (used to determine if no convergence) */ 00435 conv_err = 0.0; 00436 for (i = 0; i < NUM_STRUTS; i++) { 00437 conv_err += fabs(StrutLengthDiff[i]); 00438 } 00439 00440 /* enter loop to determine if a strut needs another iteration */ 00441 iterate = 0; /*assume iteration is done */ 00442 for (i = 0; i < NUM_STRUTS; i++) { 00443 if (fabs(StrutLengthDiff[i]) > conv_criterion) { 00444 iterate = 1; 00445 } 00446 } 00447 } /* exit Newton-Raphson Iterative loop */ 00448 00449 /* assign r,p,w to a,b,c */ 00450 pos->a = q_RPY.r * 180.0 / PM_PI; 00451 pos->b = q_RPY.p * 180.0 / PM_PI; 00452 pos->c = q_RPY.y * 180.0 / PM_PI; 00453 00454 /* assign q_trans to pos */ 00455 pos->tran.x = q_trans.x; 00456 pos->tran.y = q_trans.y; 00457 pos->tran.z = q_trans.z; 00458 00459 return retval; 00460 } |
|
Definition at line 500 of file genhexkins.c. 00504 { 00505 *fflags = 0; 00506 *iflags = 0; 00507 00508 return kinematicsInverse(world, joint, iflags, fflags); 00509 } |
|
Definition at line 464 of file genhexkins.c. 00468 { 00469 PmCartesian aw, temp; 00470 PmRotationMatrix RMatrix; 00471 PmRpy rpy; 00472 int i; 00473 00474 /* define Rotation Matrix */ 00475 rpy.r = pos->a * PM_PI / 180.0; 00476 rpy.p = pos->b * PM_PI / 180.0; 00477 rpy.y = pos->c * PM_PI / 180.0; 00478 pmRpyMatConvert(rpy, &RMatrix); 00479 00480 /* enter for loop to calculate joints (strut lengths) */ 00481 for (i = 0; i < NUM_STRUTS; i++) { 00482 /* convert location of platform strut end from platform 00483 to world coordinates */ 00484 pmMatCartMult(RMatrix, a[i], &temp); 00485 pmCartCartAdd(pos->tran, temp, &aw); 00486 00487 /* define strut lengths */ 00488 pmCartCartSub(aw, b[i], &temp); 00489 pmCartMag(temp, &joints[i]); 00490 } 00491 00492 return 0; 00493 } |
|
|
|
Definition at line 511 of file genhexkins.c. Referenced by init_module().
00512 { 00513 #if 1 00514 return KINEMATICS_BOTH; 00515 #else 00516 return KINEMATICS_INVERSE_ONLY; 00517 #endif 00518 } |