Main Page   Class Hierarchy   Alphabetical List   Data Structures   File List   Data Fields   Globals  

usrmotintf.c

Go to the documentation of this file.
00001 /*
00002   usrmotintf.c
00003 
00004   Defs for interface functions (init, exit, read, write) for user
00005   processes which communicate with the real-time motion controller
00006   in emcmot.c
00007 
00008   Modification history:
00009 
00010   15-Aug-2001  FMP added printing of axisLimitVel
00011   1-Jun-2001  FMP added printing of debug in config status
00012   21-May-2001  FMP took out FIFO stuff since it's not used anymore
00013   25-Jan-2001 WPS modified code so that if NO_RTL is defined we fake things
00014   just like we do for non-linux systems.
00015   16-Aug-2000  FMP added usrmotAlter()
00016   14-Aug-2000  FMP added return -1 to case when mbuff can't connect,
00017   to keep from dumping core
00018   10-Aug-2000  FMP added some more error checking for usrmotLoadComp();
00019   changed comp table structure a bit, removing fwd,revavgint in favor of
00020   a single avgint, to do input comp rather than output comp.
00021   8-Aug-2000  FMP added EMCMOT_COMPENSATION loading; took out commented
00022   btostr function
00023   28-Jun-2000 WPS if 0'd out btostr which wasn't being used and added
00024   __attribute__((unused)) to ident.
00025   7-Mar-2000  FMP added deadband to printing.
00026   17-Feb-2000  FMP took off extra newline in POS_VOLTAGE log dumping.
00027   19-Jan-2000 WPS added code for more verbose flags show.
00028   17-Nov-1999 WPS added code to use rtai_shm.
00029   3-Nov-1999  FMP added EMCMOT_LOG_POS_VOLTAGE
00030   5-Oct-1999  FMP added printing of minFerror[]
00031   29-Sep-1999  FMP added printing of homeOffset[]
00032   16-Jun-1999  FMP added printing of axisPos[]
00033   8-Jun-1999  FMP changed floating point format from %e (6 digits after
00034   the decimal point) to %10 (10 digits after the decimal point). Added
00035   printing of limitVel
00036   7-Jun-1999  FMP changed floating point format for logging from %f to %e
00037   for logged data; added 'mag' value for vel and acc
00038   3-Jun-1999  FMP fixed logging of traj pos, vel, acc
00039   21-May-1999  FMP added logging of traj pos, vel, acc
00040   8-May-1999  FMP added printing of fifo dev names if they can't be opened,
00041   and added a perror on fifo write errors
00042   26-Mar-1999  FMP put proper timeout code in usrmotWriteEmcmotCommand
00043   so that EMCMOT_COMM_TIMEOUT is honored
00044   8-Mar-1999  RSB commented esleep out in usrmotWriteEmcmotCommand(..)
00045   25-Feb-1999  FMP added commandEcho to printed status
00046   7-Feb-1999  FMP added EMCMOT_LOG_TYPE_ALL_FERROR for following error
00047   19-Jan-1999 WPS fixed %lf in sscanf format for EMCMOT_COMM_TIMEOUT and
00048   EMCMOT_COMM_WAIT
00049   20-Aug-1998  FMP took logSize out of usrmotDumpLog(), since it's
00050   in the log header; took out read of status in usrmotDumpLog() to get
00051   type, since sometimes read fails due to split read, and type is now
00052   in each item anyway.
00053   18-Aug-1998  FMP took out printing of reverse PID gains, added bias
00054   6-Jul-1998  FMP added usrmotGetArgs(); changed BASE_ADDRESS to
00055   SHMEM_BASE_ADDRESS
00056   5-Jun-1998  FMP added printing of reverse PID gains
00057   28-May-1998  FMP added EMCMOT_COMM_ error return values instead of -1
00058   22-May-1998  FMP ifdef'ed out MAP_FAILED since it's now in mman.h for
00059   kernel 2.0.32
00060   14-Apr-1998  FMP added backlash to printing
00061   6-Apr-1998  FMP added inited flag
00062   27-Mar-1998  FMP added rcslib shared memory
00063   9-Mar-1998  FMP closed mmap file descriptor once used
00064   23-Feb-1998  FMP added commanded output logging
00065   13-Feb-1998  FMP checked commandStatus from emcmot after command sent,
00066   adding EMCMOT_COMM_ error decls
00067   6-Feb-1998  FMP added log types
00068   12-Jan-1998 FMP put RT_FIFO compile switch in
00069   7-Jan-1998  FMP changed mmap of size 0x100000 to sizeof(EMCMOT_STRUCT)
00070   15-Nov-1997  FMP fixed bug in htostr, where arg was char instead of short
00071   15-Aug-1997  FMP added printing of pid maxError
00072   16-Jul-1997  FMP added printing of motion ids
00073   10-Jul-1997  FMP created from functions in usrmot.c
00074   */
00075 
00076 
00077 /* ident tag */
00078 #ifndef __GNUC__
00079 #ifndef __attribute__
00080 #define __attribute__(x)
00081 #endif
00082 #endif
00083 
00084 static char __attribute__((unused)) ident[] = "$Id: usrmotintf.c,v 1.19 2001/11/05 16:59:55 wshackle Exp $";
00085 
00086 #include <stdio.h>
00087 #include <string.h>             /* memcpy() */
00088 #include <stdlib.h>             /* sizeof() */
00089 #include <float.h>              /* DBL_MIN */
00090 #include "_timer.h"             /* rcslib esleep() */
00091 #include "_shm.h"               /* rcslib shm_t, rcs_shm_open(), ... */
00092 #include "rcs_prnt.hh"          /* set_rcs_print_destination(), ... */
00093 #include "emcmot.h"             /* EMCMOT_STATUS,CMD */
00094 #include "emcmotcfg.h"          /* EMCMOT_ERROR_NUM,LEN */
00095 #include "emcmotglb.h"          /* SHMEM_BASE_ADDRESS, SHMEM_KEY */
00096 #include "usrmotintf.h"         /* these decls */
00097 #include "emcmotlog.h"          /* EMCMOT_LOG */
00098 #include "inifile.h"            /* iniFind() */
00099 
00100 #ifdef linux
00101 
00102 /* Linux uses mmap-style comm with RT process */
00103 #include <stdio.h>
00104 #include <errno.h>
00105 #include <sys/time.h>
00106 #include <sys/types.h>
00107 #include <sys/stat.h>
00108 #include <fcntl.h>
00109 #include <unistd.h>
00110 #include <sys/ioctl.h>
00111 
00112 #define READ_TIMEOUT_SEC 0      /* seconds for timeout */
00113 #define READ_TIMEOUT_USEC 100000 /* microseconds for timeout */
00114 
00115 #ifdef HAVE_RTAI
00116 #include <stdlib.h>
00117 #include <stdio.h>
00118 #include <unistd.h>
00119 #include <signal.h>
00120 #include <sys/types.h>
00121 #include <sys/stat.h>
00122 #include <fcntl.h>
00123 #include <sys/mman.h>
00124 #include <errno.h>
00125 #include <unistd.h>
00126 
00127 #include "rtai_shm.h"
00128 #endif
00129 
00130 #ifndef NO_RTL
00131 #if defined(linux_2_2) || defined(linux_2_3) || defined(linux_2_4)
00132 #include "mbuff.h"              /* mbuff_alloc(),mbuff_free() */
00133 #define USE_RTL_MBUFF
00134 #else
00135 #include <sys/mman.h>           /* mmap, munmap, PROT_READ */
00136 #ifndef MAP_FAILED              /* kernel 2.0.29 left this out */
00137 #define MAP_FAILED ((void *) -1)
00138 #endif
00139 #endif /* linux_2_2, linux_2_3, linux_2_4 */
00140 
00141 #endif /* not NO_RTL */
00142 
00143 #endif /* linux */
00144 
00145 static int inited = 0;          /* flag if inited */
00146 static int usingShmem = 0;
00147 static shm_t *shmem = NULL;
00148 
00149 static EMCMOT_COMMAND *emcmotCommand = 0;
00150 static EMCMOT_STATUS *emcmotStatus = 0;
00151 static EMCMOT_CONFIG *emcmotConfig = 0;
00152 static EMCMOT_DEBUG *emcmotDebug = 0;
00153 static EMCMOT_ERROR *emcmotError = 0;
00154 static EMCMOT_LOG *emcmotLog = 0;
00155 static EMCMOT_COMP *emcmotComp[EMCMOT_MAX_AXIS] = {0};
00156 static EMCMOT_STRUCT *emcmotStruct = 0;
00157 
00158 /* usrmotIniLoad() loads params (SHMEM_KEY, SHMEM_BASE_ADDRESS,
00159    COMM_TIMEOUT, COMM_WAIT) from named ini file */
00160 int usrmotIniLoad(const char *filename)
00161 {
00162   FILE *fp;
00163   const char *inistring;
00164   int saveInt;
00165   double saveDouble;
00166 
00167   /* open it */
00168   if (NULL == (fp = fopen(filename, "r")))
00169   {
00170     rcs_print("can't find emcmot ini file %s\n", filename);
00171     return -1;
00172   }
00173 
00174   saveInt = SHMEM_KEY;
00175   if (NULL != (inistring = iniFind(fp, "SHMEM_KEY", "EMCMOT")))
00176   {
00177     if (1 == sscanf(inistring, "%i", &SHMEM_KEY))
00178     {
00179       /* found it */
00180     }
00181     else
00182     {
00183       /* found, but invalid */
00184       SHMEM_KEY = saveInt;
00185       rcs_print("invalid [EMCMOT] SHMEM_KEY in %s (%s); using default %d\n",
00186                 filename, inistring, SHMEM_KEY);
00187     }
00188   }
00189   else
00190   {
00191     /* not found, using default */
00192     rcs_print("[EMCMOT] SHMEM_KEY not found in %s; using default %d\n",
00193               filename, SHMEM_KEY);
00194   }
00195 
00196   saveInt = SHMEM_BASE_ADDRESS;
00197   if (NULL != (inistring = iniFind(fp, "SHMEM_BASE_ADDRESS", "EMCMOT")))
00198   {
00199     if (1 == sscanf(inistring, "%lu", &SHMEM_BASE_ADDRESS))
00200     {
00201       /* found it */
00202     }
00203     else
00204     {
00205       /* found, but invalid */
00206       SHMEM_BASE_ADDRESS = saveInt;
00207       rcs_print("invalid [EMCMOT] SHMEM_BASE_ADDRESS in %s (%s); using default %d\n",
00208                 filename, inistring, SHMEM_BASE_ADDRESS);
00209     }
00210   }
00211   else
00212   {
00213     /* not found, using default */
00214     rcs_print("[EMCMOT] SHMEM_BASE_ADDRESS not found in %s; using default %d\n",
00215               filename, SHMEM_BASE_ADDRESS);
00216 
00217   }
00218 
00219   saveDouble = EMCMOT_COMM_TIMEOUT;
00220   if (NULL != (inistring = iniFind(fp, "COMM_TIMEOUT", "EMCMOT")))
00221   {
00222     if (1 == sscanf(inistring, "%lf", &EMCMOT_COMM_TIMEOUT))
00223     {
00224       /* found it */
00225     }
00226     else
00227     {
00228       /* found, but invalid */
00229       EMCMOT_COMM_TIMEOUT = saveDouble;
00230       rcs_print("invalid [EMCMOT] COMM_TIMEOUT in %s (%s); using default %f\n",
00231                 filename, inistring, EMCMOT_COMM_TIMEOUT);
00232     }
00233   }
00234   else
00235   {
00236     /* not found, using default */
00237     rcs_print("[EMCMOT] COMM_TIMEOUT not found in %s; using default %f\n",
00238               filename, EMCMOT_COMM_TIMEOUT);
00239   }
00240 
00241   saveDouble = EMCMOT_COMM_WAIT;
00242   if (NULL != (inistring = iniFind(fp, "COMM_WAIT", "EMCMOT")))
00243   {
00244     if (1 == sscanf(inistring, "%lf", &EMCMOT_COMM_WAIT))
00245     {
00246       /* found it */
00247     }
00248     else
00249     {
00250       /* found, but invalid */
00251       EMCMOT_COMM_WAIT = saveDouble;
00252       rcs_print("invalid [EMCMOT] COMM_WAIT in %s (%s); using default %f\n",
00253                 filename, inistring, EMCMOT_COMM_WAIT);
00254     }
00255   }
00256   else
00257   {
00258     /* not found, using default */
00259     rcs_print("[EMCMOT] COMM_WAIT not found in %s; using default %f\n",
00260               filename, EMCMOT_COMM_WAIT);
00261   }
00262 
00263   fclose(fp);
00264 
00265   return 0;
00266 }
00267 
00268 int emcmot_comm_timeout_count = 0;
00269 
00270 /* writes command from c */
00271 int usrmotWriteEmcmotCommand(EMCMOT_COMMAND * c)
00272 {
00273   EMCMOT_STATUS s;
00274   static int commandNum = 0;
00275   static unsigned char headCount = 0;
00276   double end;
00277 
00278   c->head = ++headCount;
00279   c->tail = c->head;
00280   c->commandNum = ++commandNum;
00281 
00282   if (usingShmem)
00283   {
00284     /* check for shmem still around */
00285     if (0 == emcmotCommand)
00286     {
00287       return EMCMOT_COMM_ERROR_CONNECT;
00288     } /* end of if */
00289 
00290     *emcmotCommand = *c;
00291   } /* end of if */
00292   else
00293   {
00294     /* check for mapped mem still around */
00295     if (0 == emcmotCommand)
00296     {
00297       return EMCMOT_COMM_ERROR_CONNECT;
00298     } /* end of if */
00299 
00300     *emcmotCommand = *c;
00301   } /* end of else */
00302 
00303   /* poll for receipt of command */
00304 
00305   /* set timeout for comm failure, now + timeout */
00306   end = etime() + EMCMOT_COMM_TIMEOUT;
00307 
00308   /* now check to see if it got it */
00309   while (etime() < end)
00310   {
00311     /* update status */
00312     if (0 == usrmotReadEmcmotStatus(&s) &&
00313         s.commandNumEcho == commandNum)
00314     {
00315       /* now check emcmot status flag */
00316       if (s.commandStatus == EMCMOT_COMMAND_OK)
00317       {
00318         return EMCMOT_COMM_OK;
00319       } /* end of if */
00320       else
00321       {
00322         return EMCMOT_COMM_ERROR_COMMAND;
00323       } /* end of else */
00324     } /* end of if */
00325     /* rcs_print("s.commandNumEcho = %d, commandNum=%d\n",s.commandNumEcho, commandNum); */
00326   } /* end of while loop */
00327 
00328   emcmot_comm_timeout_count++;
00329   /*  rcs_print("emcmot_comm_timeout_count=%d\n", emcmot_comm_timeout_count); */
00330   return EMCMOT_COMM_ERROR_TIMEOUT;
00331 }
00332 
00333 int emcmot_status_split_count=0;
00334 int emcmot_config_split_count=0;
00335 int emcmot_debug_split_count=0;
00336 
00337 /* copies status to s */
00338 int usrmotReadEmcmotStatus(EMCMOT_STATUS * s)
00339 {
00340   if (usingShmem)
00341   {
00342     /* check for shmem still around */
00343     if (0 == emcmotStatus)
00344     {
00345       return EMCMOT_COMM_ERROR_CONNECT;
00346     }
00347 
00348     memcpy(s, emcmotStatus, sizeof(EMCMOT_STATUS));
00349   }
00350   else
00351   {
00352     /* check for shmem still around */
00353     if (0 == emcmotStatus)
00354     {
00355       return EMCMOT_COMM_ERROR_CONNECT;
00356     }
00357 
00358     memcpy(s, emcmotStatus, sizeof(EMCMOT_STATUS));
00359   }
00360 
00361   /* got it, now check head-tail matches */
00362 #ifndef IGNORE_SPLIT_READS
00363   if (s->head != s->tail)
00364   {
00365 #if 0
00366     emcmot_status_split_count++;
00367     if (emcmot_status_split_count > 2 && emcmot_status_split_count%100 == 0)
00368     {
00369       rcs_print("emcmot_status_split_count = %d\n",emcmot_status_split_count);
00370     }
00371 #endif
00372     return EMCMOT_COMM_SPLIT_READ_TIMEOUT;
00373   }
00374 #endif
00375 
00376   emcmot_status_split_count = 0;
00377   return EMCMOT_COMM_OK;
00378 }
00379 
00380 
00381 /* copies config to s */
00382 int usrmotReadEmcmotConfig(EMCMOT_CONFIG * s)
00383 {
00384   if (usingShmem)
00385   {
00386     /* check for shmem still around */
00387     if (0 == emcmotConfig)
00388     {
00389       return EMCMOT_COMM_ERROR_CONNECT;
00390     }
00391 
00392     memcpy(s, emcmotConfig, sizeof(EMCMOT_CONFIG));
00393   }
00394   else
00395   {
00396     /* check for shmem still around */
00397     if (0 == emcmotConfig)
00398     {
00399       return EMCMOT_COMM_ERROR_CONNECT;
00400     }
00401 
00402     memcpy(s, emcmotConfig, sizeof(EMCMOT_CONFIG));
00403   }
00404 
00405   /* got it, now check head-tail matches */
00406 #ifndef IGNORE_SPLIT_READS
00407   if (s->head != s->tail)
00408   {
00409 #if 0
00410     emcmot_config_split_count++;
00411     if (emcmot_config_split_count > 2 && emcmot_config_split_count%100 == 0)
00412     {
00413       rcs_print("emcmot_config_split_count = %d\n",emcmot_config_split_count);
00414     }
00415 #endif
00416     return EMCMOT_COMM_SPLIT_READ_TIMEOUT;
00417   }
00418 #endif
00419 
00420   emcmot_config_split_count = 0;
00421   return EMCMOT_COMM_OK;
00422 }
00423 
00424 /* copies debug to s */
00425 int usrmotReadEmcmotDebug(EMCMOT_DEBUG * s)
00426 {
00427   if (usingShmem)
00428   {
00429     /* check for shmem still around */
00430     if (0 == emcmotDebug)
00431     {
00432       return EMCMOT_COMM_ERROR_CONNECT;
00433     }
00434 
00435     memcpy(s, emcmotDebug, sizeof(EMCMOT_DEBUG));
00436   }
00437   else
00438   {
00439     /* check for shmem still around */
00440     if (0 == emcmotDebug)
00441     {
00442       return EMCMOT_COMM_ERROR_CONNECT;
00443     }
00444 
00445     memcpy(s, emcmotDebug, sizeof(EMCMOT_DEBUG));
00446   }
00447 
00448   /* got it, now check head-tail matches */
00449 #ifndef IGNORE_SPLIT_READS
00450   if (s->head != s->tail)
00451   {
00452 #if 0
00453     emcmot_debug_split_count++;
00454     if (emcmot_debug_split_count > 2 && emcmot_debug_split_count%100 == 0)
00455     {
00456       rcs_print("emcmot_debug_split_count = %d\n",emcmot_debug_split_count);
00457     }
00458 #endif
00459     return EMCMOT_COMM_SPLIT_READ_TIMEOUT;
00460   }
00461 #endif
00462 
00463   emcmot_debug_split_count = 0;
00464   return EMCMOT_COMM_OK;
00465 }
00466 
00467 /* copies error to s */
00468 int usrmotReadEmcmotError(char *e)
00469 {
00470   /* check to see if ptr still around */
00471   if (emcmotError == 0)
00472   {
00473     return -1;
00474   }
00475 
00476   /* returns 0 if something, -1 if not */
00477   return emcmotErrorGet(emcmotError, e);
00478 }
00479 
00480 /*
00481  htostr()
00482 
00483  converts short int to 0-1 style string, in s. Assumes a short is 2 bytes.
00484 */
00485 static int htostr(char * s, unsigned short h)
00486 {
00487   int t;
00488 
00489   for (t = 15; t >= 0; t--)
00490     {
00491       s[t] = h % 2 ? '1' : '0';
00492       h >>= 1;
00493     }
00494   s[16] = 0;                    /* null terminate */
00495 
00496   return 0;
00497 }
00498 
00499 void printEmcPose(EmcPose *pose)
00500 {
00501   printf("x=%f\ty=%f\tz=%f\ta=%f\tb=%f\tc=%f",
00502          pose->tran.x, pose->tran.y, pose->tran.z, pose->a,pose->b,pose->c);
00503 }
00504 
00505 
00506 void printTPstruct(TP_STRUCT *tp)
00507 {
00508   printf("queueSize=%d\n",tp->queueSize);
00509   printf("cycleTime=%f\n",tp->cycleTime);
00510   printf("vMax=%f\n",tp->vMax);
00511   printf("vScale=%f\n",tp->vScale);
00512   printf("vRestore=%f\n",tp->vRestore);
00513   printf("aMax=%f\n",tp->aMax);
00514   printf("vLimit=%f\n",tp->vLimit);
00515   printf("wMax=%f\n",tp->wMax);
00516   printf("wDotMax=%f\n",tp->wDotMax);
00517   printf("nextId=%d\n",tp->nextId);
00518   printf("execId=%d\n",tp->execId);
00519   printf("termCond=%d\n",tp->termCond);
00520   printf("currentPos :");
00521   printEmcPose(&tp->currentPos);
00522   printf("\n");
00523   printf("goalPos :");
00524   printEmcPose(&tp->goalPos);
00525   printf("\n");
00526   printf("done=%d\n",tp->done);
00527   printf("depth=%d\n",tp->depth);
00528   printf("activeDepth=%d\n",tp->activeDepth);
00529   printf("aborting=%d\n",tp->aborting);
00530   printf("pausing=%d\n",tp->pausing);
00531 }
00532 
00533 void usrmotPrintEmcmotDebug(EMCMOT_DEBUG d, int which)
00534 {
00535   int t;
00536 
00537   printf("running time: \t%f\n", d.running_time);
00538   switch(which)
00539     {
00540     case 0:
00541       printf("split:        \t%d\n", d.split);
00542       printf("teleop desiredVel: \t%f\t%f\t%f\t%f\t%f\t%f\n",
00543              d.teleop_data.desiredVel.tran.x, 
00544              d.teleop_data.desiredVel.tran.y,
00545              d.teleop_data.desiredVel.tran.z,
00546              d.teleop_data.desiredVel.a,
00547              d.teleop_data.desiredVel.b,
00548              d.teleop_data.desiredVel.c);
00549       printf("teleop currentVel: \t%f\t%f\t%f\t%f\t%f\t%f\n",
00550              d.teleop_data.currentVel.tran.x, 
00551              d.teleop_data.currentVel.tran.y,
00552              d.teleop_data.currentVel.tran.z,
00553              d.teleop_data.currentVel.a,
00554              d.teleop_data.currentVel.b,
00555              d.teleop_data.currentVel.c);
00556       printf("teleop desiredAccell: \t%f\t%f\t%f\t%f\t%f\t%f\n",
00557              d.teleop_data.desiredAccell.tran.x, 
00558              d.teleop_data.desiredAccell.tran.y,
00559              d.teleop_data.desiredAccell.tran.z,
00560              d.teleop_data.desiredAccell.a,
00561              d.teleop_data.desiredAccell.b,
00562              d.teleop_data.desiredAccell.c);
00563       printf("teleop currentAccell: \t%f\t%f\t%f\t%f\t%f\t%f\n",
00564              d.teleop_data.currentAccell.tran.x, 
00565              d.teleop_data.currentAccell.tran.y,
00566              d.teleop_data.currentAccell.tran.z,
00567              d.teleop_data.currentAccell.a,
00568              d.teleop_data.currentAccell.b,
00569              d.teleop_data.currentAccell.c);
00570       break;
00571       printf("\nferror:        ");
00572       for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00573         {
00574           printf("\t%f", d.ferrorCurrent[t]);
00575         }
00576       printf("\n");
00577       
00578       printf("\nferror High:        ");
00579       for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00580         {
00581           printf("\t%f", d.ferrorHighMark[t]);
00582         }
00583       printf("\n");
00584 
00585     case 5:
00586       printf("traj  m/m/a:\t%f\t%f\t%f\n", d.tMin, d.tMax, d.tAvg);
00587       printf("tMmxavg : sum=%f, in=%d, size=%d, index=%d\n",
00588              d.tMmxavg.sum, d.tMmxavg.in, d.tMmxavg.size, d.tMmxavg.index);
00589 #if 0
00590       if(  d.tMmxavg.in > 0  && d.tMmxavg.size > 0)
00591         {
00592           printf("tMmxavg : nums \n\t ");
00593           for(t = 0; t < d.tMmxavg.in && t < d.tMmxavg.size; t++)
00594             {
00595               printf("%3.3e \t",d.tMmxavgSpace[t]);
00596               if(t%8 == 0 && t>0)
00597                 {
00598                   printf("\n\t ");
00599                 }
00600             }
00601         }
00602 #endif
00603       printf("\n");
00604       printf("servo m/m/a:\t%f\t%f\t%f\n", d.sMin, d.sMax, d.sAvg);
00605       printf("sMmxavg : sum=%f, in=%d, size=%d, index=%d\n",
00606              d.sMmxavg.sum, d.sMmxavg.in, d.sMmxavg.size, d.sMmxavg.index);
00607 
00608 #if 0
00609       if(  d.sMmxavg.in > 0  && d.sMmxavg.size > 0)
00610         {
00611           printf("sMmxavg : nums \n\t ");
00612           for(t = 0; t < d.sMmxavg.in && t < d.sMmxavg.size; t++)
00613             {
00614               printf("%3.3e \t",d.sMmxavgSpace[t]);
00615               if(t%8 == 0 && t>0)
00616                 {
00617                   printf("\n\t ");
00618                 }
00619             }
00620         }
00621 #endif
00622       printf("\n");
00623       printf("(off) m/m/a:\t%f\t%f\t%f\n", d.nMin, d.nMax, d.nAvg);
00624       printf("nMmxavg : sum=%f, in=%d, size=%d, index=%d\n",
00625              d.nMmxavg.sum, d.nMmxavg.in, d.nMmxavg.size, d.nMmxavg.index);
00626 #if 0
00627       if(  d.nMmxavg.in > 0  && d.nMmxavg.size > 0)
00628         {
00629           printf("nMmxavg : nums \n\t ");
00630           for(t = 0; t < d.nMmxavg.in && t < d.nMmxavg.size; t++)
00631             {
00632               printf("%3.3e \t",d.nMmxavgSpace[t]);
00633               if(t%8 == 0 && t>0)
00634                 {
00635               printf("\n\t ");
00636                 }
00637             }
00638         }
00639 #endif
00640       printf("\n");
00641 
00642       printf("(cycle to cycle  time) m/m/a:\t%f\t%f\t%f\n", d.yMin, d.yMax, d.yAvg);
00643       printf("yMmxavg : sum=%f, in=%d, size=%d, index=%d\n",
00644              d.yMmxavg.sum, d.yMmxavg.in, d.yMmxavg.size, d.yMmxavg.index);
00645 #if 0
00646       if(  d.yMmxavg.in > 0  && d.yMmxavg.size > 0)
00647         {
00648           printf("nMmxavg : nums \n\t ");
00649           for(t = 0; t < d.yMmxavg.in && t < d.yMmxavg.size; t++)
00650             {
00651               printf("%3.3e \t",d.yMmxavgSpace[t]);
00652               if(t%8 == 0 && t>0)
00653                 {
00654               printf("\n\t ");
00655                 }
00656             }
00657         }
00658 #endif
00659 
00660       printf("\n");
00661 
00662 
00663       printf("(frequency compute  time) m/m/a:\t%f\t%f\t%f\n", d.fMin, d.fMax, d.fAvg);
00664       printf("fMmxavg : sum=%f, in=%d, size=%d, index=%d\n",
00665              d.fMmxavg.sum, d.fMmxavg.in, d.fMmxavg.size, d.fMmxavg.index);
00666 #if 0
00667       if(  d.fMmxavg.in > 0  && d.fMmxavg.size > 0)
00668         {
00669           printf("nMmxavg : nums \n\t ");
00670           for(t = 0; t < d.fMmxavg.in && t < d.fMmxavg.size; t++)
00671             {
00672               printf("%3.3e \t",d.fMmxavgSpace[t]);
00673               if(t%8 == 0 && t>0)
00674                 {
00675               printf("\n\t ");
00676                 }
00677             }
00678         }
00679 #endif
00680 
00681       printf("\n");
00682 
00683 
00684       printf("(frequecy cycle to cycle  time) m/m/a:\t%f\t%f\t%f\n", d.fyMin, d.fyMax, d.fyAvg);
00685       printf("nMmxavg : sum=%f, in=%d, size=%d, index=%d\n",
00686              d.fyMmxavg.sum, d.fyMmxavg.in, d.fyMmxavg.size, d.fyMmxavg.index);
00687 #if 0
00688       if(  d.fyMmxavg.in > 0  && d.fyMmxavg.size > 0)
00689         {
00690           printf("nMmxavg : nums \n\t ");
00691           for(t = 0; t < d.fyMmxavg.in && t < d.fyMmxavg.size; t++)
00692             {
00693               printf("%3.3e \t",d.fyMmxavgSpace[t]);
00694               if(t%8 == 0 && t>0)
00695                 {
00696               printf("\n\t ");
00697                 }
00698             }
00699         }
00700 #endif
00701 
00702       printf("\n");
00703       break;
00704       
00705     case 6:
00706     case 7:
00707     case 8:
00708     case 9:
00709     case 10:
00710     case 11:
00711       printf("freeAxis[%d]:\n",which-6);
00712       printTPstruct(&d.freeAxis[which-6]);
00713       break;
00714 
00715     case 12:
00716       printf("\noldInput:  ");
00717       for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00718         {
00719           printf("\t%f", d.oldInput[t]);
00720         }
00721       printf("\nrawInput:  ");
00722       for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00723         {
00724           printf("\t%f", d.rawInput[t]);
00725         }
00726       printf("\ninverseInputScale:  ");
00727       for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00728         {
00729           printf("\t%f", d.inverseInputScale[t]);
00730         }
00731       printf("\nbcompincr:  ");
00732       for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00733         {
00734           printf("\t%f", d.bcompincr[t]);
00735         }
00736       
00737     default:
00738       break;
00739     }
00740 
00741 }
00742 
00743 
00744 void usrmotPrintEmcmotConfig(EMCMOT_CONFIG c, int which)
00745 {
00746   int t;
00747   char m[32];
00748 
00749   switch(which)
00750     {
00751     case 0:
00752       printf("debug level   \t%d\n", c.debug);
00753       printf("traj time:    \t%f\n", c.trajCycleTime);
00754       printf("servo time:   \t%f\n", c.servoCycleTime);
00755       printf("interp rate:  \t%d\n", c.interpolationRate);
00756       printf("v limit:      \t%f\n", c.limitVel);
00757       printf("axis vlimit:  \t");
00758       for (t = 0; t < EMCMOT_MAX_AXIS; t++) {
00759         printf("%f ", c.axisLimitVel[t]);
00760       }
00761       printf("\n");
00762       printf("probe index: %d\n",c.probeIndex);
00763       printf("probe polarity: %d\n",c.probePolarity);
00764       for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00765         {
00766           htostr(m, c.axisPolarity[t]);
00767           printf("%s ", m);
00768         }
00769       printf("\n");
00770       break;
00771 
00772   case 1:
00773     printf("pid:\tP\tI\tD\tFF0\tFF1\tFF2\tBCKLSH\tBIAS\tMAXI\tDEADBAND\tCYCLE TIME\n");
00774     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00775     {
00776       printf("\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%f\t%f\n",
00777              c.pid[t].p, c.pid[t].i, c.pid[t].d,
00778              c.pid[t].ff0, c.pid[t].ff1, c.pid[t].ff2,
00779              c.pid[t].backlash, c.pid[t].bias,
00780              c.pid[t].maxError, c.pid[t].deadband, c.pid[t].cycleTime);
00781     }
00782     printf("\n");
00783     break;
00784 
00785 
00786   case 3:
00787     printf("pos limits:   ");
00788     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00789     {
00790       printf("\t%f", c.maxLimit[t]);
00791     }
00792 
00793     printf("\nneg limits:   ");
00794     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00795     {
00796       printf("\t%f", c.minLimit[t]);
00797     }
00798 
00799     printf("\nmax output:   ");
00800     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00801     {
00802       printf("\t%f", c.maxOutput[t]);
00803     }
00804 
00805     printf("\nmin output:   ");
00806     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00807     {
00808       printf("\t%f", c.minOutput[t]);
00809     }
00810 
00811     printf("\nmax ferror:   ");
00812     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00813     {
00814       printf("\t%f", c.maxFerror[t]);
00815     }
00816     printf("\n");
00817 
00818     printf("\nmin ferror:   ");
00819     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00820     {
00821       printf("\t%f", c.minFerror[t]);
00822     }
00823     printf("\n");
00824 
00825     printf("\nhome offsets:  ");
00826     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00827     {
00828       printf("\t%f", c.homeOffset[t]);
00829     }
00830     printf("\n");
00831 
00832 
00833     break;
00834 
00835 
00836       
00837     default:
00838       break;
00839     }
00840 
00841 }
00842 
00843 
00844 /* status printing function */
00845 void usrmotPrintEmcmotStatus(EMCMOT_STATUS s, int which)
00846 {
00847   int t;
00848   char m[32];
00849 
00850   switch (which)
00851   {
00852   case 0:
00853     printf("mode:         \t%s\n",
00854            s.motionFlag & EMCMOT_MOTION_TELEOP_BIT ? "teleop" :
00855            (s.motionFlag & EMCMOT_MOTION_COORD_BIT ? "coord" : "free")
00856            );
00857     printf("cmd:          \t%d\n", s.commandEcho);
00858     printf("cmd num:      \t%d\n", s.commandNumEcho);
00859     printf("heartbeat:    \t%u\n", s.heartbeat);
00860     printf("compute time: \t%f\n", s.computeTime);
00861     printf("axes enabled: \t");
00862     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00863     {
00864       printf("%d", s.axisFlag[t] & EMCMOT_AXIS_ENABLE_BIT ? 1 : 0);
00865     }
00866     printf("\n");
00867     printf("cmd pos:      \t%f\t%f\t%f\t%f\t%f\t%f\n",
00868            s.pos.tran.x, s.pos.tran.y, s.pos.tran.z,
00869            s.pos.a, s.pos.b, s.pos.c);
00870     printf("act pos:      \t%f\t%f\t%f\t%f\t%f\t%f\n",
00871            s.actualPos.tran.x, s.actualPos.tran.y, s.actualPos.tran.z,
00872            s.actualPos.a, s.actualPos.b, s.actualPos.c
00873            );
00874     printf("axis pos:     ");
00875     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00876     {
00877       printf("\t%f", s.axisPos[t]);
00878     }
00879     printf("\n");
00880     printf("velocity:     \t%f\n", s.vel);
00881     printf("accel:        \t%f\n", s.acc);
00882     printf("id:           \t%d\n", s.id);
00883     printf("depth:        \t%d\n", s.depth);
00884     printf("active depth: \t%d\n", s.activeDepth);
00885     printf("inpos:        \t%d\n",
00886            s.motionFlag & EMCMOT_MOTION_INPOS_BIT ? 1 : 0);
00887     printf("vscales:      \tQ: %.2f", s.qVscale);
00888     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00889     {
00890       printf("\t%d: %.2f", t, s.axVscale[t]);
00891     }
00892     printf("\n");
00893     printf("logging:      \t%s and %s, size %d, skipping %d, type %d\n",
00894            s.logOpen == 0 ? "closed" : "open",
00895            s.logStarted == 0 ? "stopped" : "started",
00896            s.logSize, s.logSkip, s.logType);
00897     printf("homing:       \t");
00898     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00899     {
00900       printf("%d", s.axisFlag[0] & EMCMOT_AXIS_HOMING_BIT ? 1 : 0);
00901     }
00902     printf("\n");
00903     printf("enabled:     \t%s\n",
00904            s.motionFlag & EMCMOT_MOTION_ENABLE_BIT ? "ENABLED" : "DISABLED");
00905 #ifdef ENABLE_PROBING
00906     printf("probe value: %d\n",s.probeval);
00907     printf("probe Tripped: %d\n",s.probeTripped);
00908     printf("probing: %d\n",s.probing);
00909     printf("probed pos:      \t%f\t%f\t%f\n",
00910            s.probedPos.tran.x, s.probedPos.tran.y, s.probedPos.tran.z);
00911 #endif
00912     break;
00913 
00914   case 2:
00915     htostr(m, s.motionFlag);
00916     printf("motion:   %s\n", m);
00917     printf("axes:     ");
00918     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00919     {
00920       htostr(m, s.axisFlag[t]);
00921       printf("%s ", m);
00922     }
00923     printf("\n");
00924     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00925     {
00926       printf("%d\t", ((s.axisFlag[t] & EMCMOT_AXIS_ENABLE_BIT) != 0));
00927     }
00928     printf("enable\n");
00929     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00930     {
00931       printf("%d\t", ((s.axisFlag[t] & EMCMOT_AXIS_ACTIVE_BIT) != 0));
00932     }
00933     printf("active\n");
00934     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00935     {
00936       printf("%d\t", ((s.axisFlag[t] & EMCMOT_AXIS_INPOS_BIT) != 0));
00937     }
00938     printf("inpos\n");
00939     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00940     {
00941       printf("%d\t", ((s.axisFlag[t] & EMCMOT_AXIS_ERROR_BIT) != 0));
00942     }
00943     printf("error\n");
00944     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00945     {
00946       printf("%d\t", ((s.axisFlag[t] & EMCMOT_AXIS_MAX_SOFT_LIMIT_BIT) != 0));
00947     }
00948     printf("max_soft_limit\n");
00949     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00950     {
00951       printf("%d\t", ((s.axisFlag[t] & EMCMOT_AXIS_MIN_SOFT_LIMIT_BIT) != 0));
00952     }
00953     printf("min_soft_limit\n");
00954     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00955     {
00956       printf("%d\t", ((s.axisFlag[t] & EMCMOT_AXIS_MAX_HARD_LIMIT_BIT) != 0));
00957     }
00958     printf("max_hard_limit\n");
00959     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00960     {
00961       printf("%d\t", ((s.axisFlag[t] & EMCMOT_AXIS_MIN_HARD_LIMIT_BIT) != 0));
00962     }
00963     printf("min_hard_limit\n");
00964     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00965     {
00966       printf("%d\t", ((s.axisFlag[t] & EMCMOT_AXIS_HOME_SWITCH_BIT) != 0));
00967     }
00968     printf("home_switch\n");
00969     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00970     {
00971       printf("%d\t", ((s.axisFlag[t] & EMCMOT_AXIS_HOMING_BIT) != 0));
00972     }
00973     printf("homing\n");
00974     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00975     {
00976       printf("%d\t", ((s.axisFlag[t] & EMCMOT_AXIS_HOMED_BIT) != 0));
00977     }
00978     printf("homed\n");
00979     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00980     {
00981       printf("%d\t", ((s.axisFlag[t] & EMCMOT_AXIS_FERROR_BIT) != 0));
00982     }
00983     printf("ferror\n");
00984     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00985     {
00986       printf("%d\t", ((s.axisFlag[t] & EMCMOT_AXIS_FAULT_BIT) != 0));
00987     }
00988     printf("fault\n");
00989     printf("\npolarity: ");
00990     printf("limit override: %d\n", s.overrideLimits);
00991     break;
00992 
00993   case 4:
00994     printf("output scales: ");
00995     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
00996     {
00997       printf("\t%f", s.outputScale[t]);
00998     }
00999 
01000     printf("\noutput offsets:");
01001     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
01002     {
01003       printf("\t%f", s.outputOffset[t]);
01004     }
01005 
01006     printf("\nscaled outputs:");
01007     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
01008     {
01009       printf("\t%f", s.output[t]);
01010     }
01011 
01012     printf("\ninput scales:  ");
01013     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
01014     {
01015       printf("\t%f", s.inputScale[t]);
01016     }
01017 
01018     printf("\ninput offsets: ");
01019     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
01020     {
01021       printf("\t%f", s.inputOffset[t]);
01022     }
01023 
01024     printf("\nscaled inputs: ");
01025     for (t = 0; t < EMCMOT_MAX_AXIS; t++)
01026     {
01027       printf("\t%f", s.input[t]);
01028     }
01029 
01030     break;
01031 
01032 
01033   default:
01034     break;
01035   }
01036 }
01037 
01038 int usrmotInit(void)
01039 {
01040   int axis;
01041 
01042 #if defined(linux) && !defined(USE_RTL_MBUFF) && !defined(HAVE_RTAI)
01043   int fd;
01044 #endif
01045   RCS_PRINT_DESTINATION_TYPE dest;
01046 
01047   usingShmem = 0;
01048 
01049   /* try OS shared memory first, inhibiting error messages */
01050   dest = get_rcs_print_destination();
01051   set_rcs_print_destination(RCS_PRINT_TO_NULL);
01052   shmem = rcs_shm_open(SHMEM_KEY, sizeof(EMCMOT_STRUCT), 0);
01053   if (NULL != shmem &&
01054       NULL != shmem->addr)
01055   {
01056     /* map shmem area into local address space */
01057     emcmotStruct = (EMCMOT_STRUCT *) shmem->addr;
01058     usingShmem = 1;
01059   }
01060   set_rcs_print_destination(dest);
01061 
01062   if (! usingShmem)
01063   {
01064 #ifdef HAVE_RTAI
01065   emcmotStruct = rtai_malloc(SHMEM_KEY,sizeof(EMCMOT_STRUCT));
01066   if (emcmotStruct == NULL)
01067     {
01068       fprintf(stderr,"rtai_alloc(%d (0x%X), %d (0x%X) ) failed\n",
01069               SHMEM_KEY, SHMEM_KEY, sizeof(EMCMOT_STRUCT), sizeof(EMCMOT_STRUCT));
01070       return -1;
01071     }
01072 #else
01073 
01074 #if !defined(linux) || defined(NO_RTL)
01075     /* only linux can use mapmem-- give up */
01076     return -1;
01077 
01078 #else
01079 
01080 #ifdef USE_RTL_MBUFF
01081     emcmotStruct = (EMCMOT_STRUCT *) mbuff_alloc("emcmotStruct",sizeof(EMCMOT_STRUCT));
01082     if (emcmotStruct == NULL)
01083     {
01084       fprintf(stderr,"mbuff_alloc failed\n");
01085       return -1;
01086     }
01087 #else
01088 
01089     /* open mem device */
01090     fd = open("/dev/mem", O_RDWR);
01091     if (fd < 0)
01092     {
01093       perror("open /dev/mem");
01094       return -1;
01095     }
01096 
01097     /* map it */
01098     emcmotStruct = (EMCMOT_STRUCT *) mmap(0, sizeof(EMCMOT_STRUCT),
01099                                           PROT_READ | PROT_WRITE,
01100                                           MAP_FILE | MAP_SHARED,
01101                                           fd, SHMEM_BASE_ADDRESS);
01102 
01103     /* close the fd since it's no longer used */
01104     close(fd);
01105 
01106     if (MAP_FAILED == emcmotStruct)
01107     {
01108       perror("mmap");
01109       return -1;
01110     }
01111 #endif /* USE_RTL_MBUFF */
01112 
01113 #endif /* linux */
01114 #endif
01115 
01116   }
01117 
01118   /* got it */
01119   emcmotCommand = &(emcmotStruct->command);
01120   emcmotStatus = &(emcmotStruct->status);
01121   emcmotDebug = &(emcmotStruct->debug);
01122   emcmotConfig = &(emcmotStruct->config);
01123   emcmotError = &(emcmotStruct->error);
01124   emcmotLog = &(emcmotStruct->log);
01125   for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
01126   {
01127     emcmotComp[axis] = &(emcmotStruct->comp[axis]);
01128   }
01129 
01130   inited = 1;
01131 
01132   return 0;
01133 }
01134 
01135 int usrmotExit(void)
01136 {
01137   int axis;
01138 
01139   if (usingShmem)
01140   {
01141     if (NULL != shmem)
01142     {
01143       rcs_shm_close(shmem);
01144       shmem = NULL;
01145     }
01146   }
01147   else
01148   {
01149 #ifdef HAVE_RTAI
01150     rtai_free(SHMEM_KEY,emcmotStruct);
01151 #else
01152 #if defined(linux) && !defined(NO_RTL)
01153 #ifdef USE_RTL_MBUFF
01154     mbuff_free("emcmotStruct", emcmotStruct);
01155 #else
01156     munmap((void *) emcmotStruct, sizeof(EMCMOT_STRUCT));
01157 #endif
01158 #endif
01159 #endif
01160   }
01161 
01162   emcmotStruct = 0;
01163   emcmotCommand = 0;
01164   emcmotStatus = 0;
01165   emcmotError = 0;
01166   emcmotLog = 0;
01167   for (axis = 0; axis < EMCMOT_MAX_AXIS; axis++)
01168   {
01169     emcmotComp[axis] = 0;
01170   }
01171 
01172   inited = 0;
01173   return 0;
01174 }
01175 
01176 /* reads the log fifo and dumps the contents to a text file */
01177 int usrmotDumpLog(const char * filename, int include_header)
01178 {
01179   FILE * fp;
01180   EMCMOT_LOG_STRUCT ls;
01181   int axis;
01182   int first_point = 1;
01183   double start_time=0;
01184   int start_time_set=0;
01185 
01186   /* open output log file */
01187   if (NULL == (fp = fopen(filename, "w")))
01188   {
01189     fprintf(stderr, "can't open dump file %s\n", filename);
01190     return -1;
01191   }
01192 
01193 
01194   /* get the data */
01195   while (emcmotLog->howmany > 0)
01196   {
01197     if (-1 == emcmotLogGet(emcmotLog, &ls))
01198     {
01199       break;
01200     }
01201 
01202 
01203   if(include_header && first_point)
01204     {
01205       first_point=0;
01206       fprintf(fp,"#!/bin/sh\n");
01207       fprintf(fp,"exec cat $0 | head -n 16 | tail -n 12 | sed s#THIS_PLOT_FILE#$0#g |  gnuplot -persist\n");
01208       fprintf(fp,"exit\n"); 
01209       fprintf(fp,"\n");
01210       
01211       fprintf(fp,"# This file contains both the gnuplot plotting instructions\n"); 
01212       fprintf(fp,"# and the data logged, by EMC.\n");
01213       fprintf(fp,"# For this to work, the data must begin after 2 blank lines,\n");
01214       fprintf(fp,"# and the line \"exit\" must appear before the data.\n");
01215       fprintf(fp,"# (lines beginning with \"#\" are ignored.)\n");
01216       fprintf(fp,"print \"Running THIS_PLOT_FILE . . .\\n\"\n");
01217       switch(ls.type)
01218         {
01219 
01220         case EMCMOT_LOG_TYPE_AXIS_POS:
01221           fprintf(fp,"print \"Plotting axis position values . . .\\n\"\n");
01222           fprintf(fp,"plot \"THIS_PLOT_FILE\" index 1 using 1:2 title \"input\",  \"THIS_PLOT_FILE\" index 1 using 1:3 title \"output\"\n");
01223           break;
01224 
01225         case EMCMOT_LOG_TYPE_ALL_OUTPOS:
01226           fprintf(fp,"print \"Plotting all output values . . .\\n\"\n");
01227           fprintf(fp,"set multiplot; set size 1,0.33; ");
01228      
01229           for (axis = 0; axis < EMCMOT_LOG_NUM_AXES; axis++)
01230             {
01231               fprintf(fp,"set origin 0,%f; plot \"THIS_PLOT_FILE\" index 1 using 1:%d title \"output[%d]\"; ", axis*0.33, axis+2, axis);
01232             }
01233           fprintf(fp, "set nomultiplot;\n");
01234           break;
01235 
01236         case EMCMOT_LOG_TYPE_ALL_INPOS:
01237           fprintf(fp,"print \"Plotting all input values . . .\\n\"\n");
01238           fprintf(fp,"set multiplot; set size 1,0.33; ");
01239      
01240           for (axis = 0; axis < EMCMOT_LOG_NUM_AXES; axis++)
01241             {
01242               fprintf(fp,"set origin 0,%f; plot \"THIS_PLOT_FILE\" index 1 using 1:%d title \"input[%d]\"; ", axis*0.33, axis+2, axis);
01243             }
01244           fprintf(fp, "set nomultiplot;\n");
01245           break;
01246 
01247 
01248 
01249         case EMCMOT_LOG_TYPE_CMD:
01250           fprintf(fp,"print \"Plotting command/commandNum values . . .\\n\"\n");
01251           fprintf(fp,"set multiplot; set size 1,0.5; plot \"THIS_PLOT_FILE\" index 1 using 1:2 title \"command\"; set origin 0,0.5; plot  \"THIS_PLOT_FILE\" index 1 using 1:3 title \"cmdNumber\"; set nomultiplot;\n");
01252           break;
01253 
01254         case EMCMOT_LOG_TYPE_AXIS_VEL:
01255           fprintf(fp,"print \"Plotting axis velocity values . . .\\n\"\n");
01256           fprintf(fp,"plot \"THIS_PLOT_FILE\" index 1 using 1:2 title \"cmdVel\",  \"THIS_PLOT_FILE\" index 1 using 1:3 title \"actualVel\"\n");
01257           break;
01258 
01259 
01260         case EMCMOT_LOG_TYPE_ALL_FERROR:
01261           fprintf(fp,"print \"Plotting all following errors. . .\\n\"\n");
01262           fprintf(fp,"set multiplot; set size 1,0.33; ");
01263      
01264           for (axis = 0; axis < EMCMOT_LOG_NUM_AXES; axis++)
01265             {
01266               fprintf(fp,"set origin 0,%f; plot \"THIS_PLOT_FILE\" index 1 using 1:%d title \"ferror[%d]\"; ", axis*0.33, axis+2, axis);
01267             }
01268           fprintf(fp, "set nomultiplot;\n");
01269           break;
01270 
01271         case EMCMOT_LOG_TYPE_TRAJ_POS:
01272           fprintf(fp,"print \"Plotting all traj positions. . .\\n\"\n");
01273           fprintf(fp,"plot \"THIS_PLOT_FILE\" index 1 using 1:2 title \"X\",  \"THIS_PLOT_FILE\" index 1 using 1:3 title \"Y\",  \"THIS_PLOT_FILE\" index 1 using 1:4 title \"Z\"\n");
01274           break;
01275 
01276         case EMCMOT_LOG_TYPE_TRAJ_VEL:
01277           fprintf(fp,"print \"Plotting all traj velocities . . .\\n\"\n");
01278           fprintf(fp,"plot \"THIS_PLOT_FILE\" index 1 using 1:2 title \"X Velocity\",  \"THIS_PLOT_FILE\" index 1 using 1:3 title \"Y Velocity\",  \"THIS_PLOT_FILE\" index 1 using 1:4 title \"Z Velocity\",  \"THIS_PLOT_FILE\" index 1 using 1:5 title \"Velocity Magnitude\"\n");
01279           break;
01280 
01281         case EMCMOT_LOG_TYPE_TRAJ_ACC: 
01282           fprintf(fp,"print \"Plotting all traj accellerations . . .\\n\"\n");
01283           fprintf(fp,"plot \"THIS_PLOT_FILE\" index 1 using 1:2 title \"X Accelleration\",  \"THIS_PLOT_FILE\" index 1 using 1:3 title \"Y Accelleration\",  \"THIS_PLOT_FILE\" index 1 using 1:4 title \"Z Accelleration\",  \"THIS_PLOT_FILE\" index 1 using 1:5 title \"Accelleration Magnitude\"\n");
01284           break;
01285 
01286 
01287         case EMCMOT_LOG_TYPE_POS_VOLTAGE:           
01288           fprintf(fp,"print \"Plotting EMC position and voltage data . . .\\n\"\n");
01289           fprintf(fp,"set multiplot; set size 1,0.5; plot \"THIS_PLOT_FILE\" index 1 using 1:2 title \"pos\"; set origin 0,0.5; plot  \"THIS_PLOT_FILE\" index 1 using 1:3 title \"volt\"; set nomultiplot;\n");
01290           break;
01291 
01292         default:
01293           fprintf(fp,"print \"Plotting unknown data values . . .\\n\"\n");
01294           fprintf(fp,"plot \"THIS_PLOT_FILE\" index 1 using 1:2 title \"data1\",  \"THIS_PLOT_FILE\" index 1 using 1:3 title \"data2\"\n");
01295           break;
01296            
01297         }
01298       fprintf(fp,"exit\n");
01299       fprintf(fp,"\n");
01300       fprintf(fp,"\n");
01301       switch(ls.type)
01302         {
01303         case EMCMOT_LOG_TYPE_AXIS_POS:
01304           fprintf(fp,"#%17.17s\t%17.17s\t%17.17s\n","time","input","output");
01305           break;
01306 
01307         case EMCMOT_LOG_TYPE_ALL_INPOS:
01308           fprintf(fp,"#%17.17s\t","time");
01309           for (axis = 0; axis < EMCMOT_LOG_NUM_AXES; axis++)
01310             {
01311               char input_name[20];;
01312               sprintf(input_name,"input[%d]",axis);
01313               fprintf(fp,"%17.17s\t",input_name);
01314             }
01315           break;
01316 
01317         case EMCMOT_LOG_TYPE_ALL_OUTPOS:
01318           fprintf(fp,"#%17.17s\t","time");
01319           for (axis = 0; axis < EMCMOT_LOG_NUM_AXES; axis++)
01320             {
01321               char input_name[20];;
01322               sprintf(input_name,"output[%d]",axis);
01323               fprintf(fp,"%17.17s\t",input_name);
01324             }
01325           fprintf(fp, "\n");
01326           break;
01327 
01328         case EMCMOT_LOG_TYPE_CMD:
01329           fprintf(fp,"#%17.17s\t%17.17s\t%17.17s\n","time","command","cmdNumber");
01330           break;
01331 
01332         case EMCMOT_LOG_TYPE_AXIS_VEL:
01333           fprintf(fp,"#%17.17s\t%17.17s\t%17.17s\n","time","cmdVel","actVel");
01334           break;
01335 
01336         case EMCMOT_LOG_TYPE_ALL_FERROR:
01337           fprintf(fp,"#%17.17s\t","time");
01338           for (axis = 0; axis < EMCMOT_LOG_NUM_AXES; axis++)
01339             {
01340               char input_name[20];;
01341               sprintf(input_name,"ferror[%d]",axis);
01342               fprintf(fp,"%17.17s\t",input_name);
01343             }
01344           fprintf(fp, "\n");
01345           break;
01346 
01347         case EMCMOT_LOG_TYPE_TRAJ_POS:
01348           fprintf(fp,"#%17.17s\t%17.17s\t%17.17s\t%17.17s\n","time","X","Y","Z");
01349           break;
01350 
01351         case EMCMOT_LOG_TYPE_TRAJ_VEL:
01352           fprintf(fp,"#%17.17s\t%17.17s\t%17.17s\t%17.17s\t%17.17s\n","time","Xvel","Yvel","Zvel","VelMag");
01353           break;
01354 
01355         case EMCMOT_LOG_TYPE_TRAJ_ACC:
01356           fprintf(fp,"#%17.17s\t%17.17s\t%17.17s\t%17.17s\t%17.17s\n","time","Xacc","Yacc","Zacc","AccMag");
01357           break;
01358 
01359         case EMCMOT_LOG_TYPE_POS_VOLTAGE:           
01360           fprintf(fp,"#%17.17s\t%17.17s\t%17.17s\n","time","pos","volt");
01361           break;
01362 
01363         default:
01364           fprintf(fp,"#\n");
01365           break;
01366         }
01367     }
01368 
01369     switch (ls.type)
01370     {
01371     case EMCMOT_LOG_TYPE_AXIS_POS:
01372       if(!start_time_set)
01373         {
01374           start_time_set=1;
01375           start_time = ls.item.axisPos.time;
01376         }
01377       fprintf(fp, "%.10e\t%.10e\t%.10e\n",
01378               ls.item.axisPos.time-start_time,
01379               ls.item.axisPos.input,
01380               ls.item.axisPos.output);
01381       break;
01382 
01383     case EMCMOT_LOG_TYPE_ALL_INPOS:
01384       if(!start_time_set)
01385         {
01386           start_time_set=1;
01387           start_time = ls.item.allInpos.time;
01388         }
01389       fprintf(fp, "%.10e", ls.item.allInpos.time);
01390       for (axis = 0; axis < EMCMOT_LOG_NUM_AXES; axis++)
01391       {
01392         fprintf(fp, "\t%.10e", ls.item.allInpos.input[axis]);
01393       }
01394       fprintf(fp, "\n");
01395       break;
01396 
01397     case EMCMOT_LOG_TYPE_ALL_OUTPOS: 
01398       if(!start_time_set)
01399         {
01400           start_time_set=1;
01401           start_time = ls.item.allOutpos.time;
01402         }
01403       fprintf(fp, "%.10e", ls.item.allOutpos.time);
01404       for (axis = 0; axis < EMCMOT_LOG_NUM_AXES; axis++)
01405       {
01406         fprintf(fp, "\t%.10e", ls.item.allOutpos.output[axis]);
01407       }
01408       fprintf(fp, "\n");
01409       break;
01410 
01411     case EMCMOT_LOG_TYPE_CMD:
01412       if(!start_time_set)
01413         {
01414           start_time_set=1;
01415           start_time = ls.item.cmd.time;
01416         }
01417       fprintf(fp, "%.10e\t%d\t%d\n",
01418               ls.item.cmd.time-start_time,
01419               ls.item.cmd.command,
01420               ls.item.cmd.commandNum);
01421       break;
01422 
01423     case EMCMOT_LOG_TYPE_AXIS_VEL:
01424       if(!start_time_set)
01425         {
01426           start_time_set=1;
01427           start_time = ls.item.axisVel.time;
01428         }
01429       fprintf(fp, "%.10e\t%.10e\t%.10e\n",
01430               ls.item.axisVel.time-start_time,
01431               ls.item.axisVel.cmdVel,
01432               ls.item.axisVel.actVel);
01433       break;
01434 
01435     case EMCMOT_LOG_TYPE_ALL_FERROR:
01436        if(!start_time_set)
01437         {
01438           start_time_set=1;
01439           start_time = ls.item.allFerror.time;
01440         }
01441        fprintf(fp, "%.10e", ls.item.allFerror.time);
01442        for (axis = 0; axis < EMCMOT_LOG_NUM_AXES; axis++)
01443          {
01444            fprintf(fp, "\t%.10e", ls.item.allFerror.ferror[axis]);
01445          }
01446        fprintf(fp, "\n");
01447        break;
01448 
01449     case EMCMOT_LOG_TYPE_TRAJ_POS:
01450        if(!start_time_set)
01451         {
01452           start_time_set=1;
01453           start_time = ls.item.trajPos.time;
01454         }
01455       fprintf(fp, "%.10e\t%.10e\t%.10e\t%.10e\n",
01456               ls.item.trajPos.time-start_time,
01457               ls.item.trajPos.pos.x,
01458               ls.item.trajPos.pos.y,
01459               ls.item.trajPos.pos.z);
01460       break;
01461 
01462     case EMCMOT_LOG_TYPE_TRAJ_VEL:
01463       if(!start_time_set)
01464         {
01465           start_time_set=1;
01466           start_time = ls.item.trajVel.time;
01467         }
01468       fprintf(fp, "%.10e\t%.10e\t%.10e\t%.10e\t%.10e\n",
01469               ls.item.trajVel.time-start_time,
01470               ls.item.trajVel.vel.x,
01471               ls.item.trajVel.vel.y,
01472               ls.item.trajVel.vel.z,
01473               ls.item.trajVel.mag);
01474       break;
01475 
01476     case EMCMOT_LOG_TYPE_TRAJ_ACC:
01477       if(!start_time_set)
01478         {
01479           start_time_set=1;
01480           start_time = ls.item.trajAcc.time;
01481         }
01482       fprintf(fp, "%.10e\t%.10e\t%.10e\t%.10e\t%.10e\n",
01483               ls.item.trajAcc.time-start_time,
01484               ls.item.trajAcc.acc.x,
01485               ls.item.trajAcc.acc.y,
01486               ls.item.trajAcc.acc.z,
01487               ls.item.trajAcc.mag);
01488       break;
01489 
01490     case EMCMOT_LOG_TYPE_POS_VOLTAGE:
01491       if(!start_time_set)
01492         {
01493           start_time_set=1;
01494           start_time = ls.item.posVoltage.time;
01495         }
01496       fprintf(fp, "%.10e\t%.10e\t%.10e\n",
01497               ls.item.posVoltage.time-start_time,
01498               ls.item.posVoltage.pos,
01499               ls.item.posVoltage.voltage);
01500       break;
01501 
01502     default:
01503       break;
01504     }
01505   }
01506 
01507   /* close output file */
01508   fclose(fp);
01509 
01510   chmod(filename, 00775);
01511   return 0;
01512 }
01513 
01514 int usrmotLoadComp(int axis, const char * file)
01515 {
01516   FILE * fp;
01517 #define BUFFERLEN 256
01518   char buffer[BUFFERLEN];
01519   double nom, fwd, rev;
01520   int index = 0;
01521   int total = 0;
01522 
01523   /* check axis range */
01524   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
01525   {
01526     fprintf(stderr, "axis out of range for compensation\n");
01527     return -1;
01528   }
01529 
01530   /* first check if comp pointer is valid */
01531   if (emcmotComp[axis] == 0)
01532   {
01533     fprintf(stderr, "compensation data structure not present\n");
01534     return -1;
01535   }
01536 
01537   /* open input comp file */
01538   if (NULL == (fp = fopen(file, "r")))
01539   {
01540     fprintf(stderr, "can't open compensation file %s\n", file);
01541     return -1;
01542   }
01543 
01544   while (! feof(fp))
01545   {
01546     if (NULL == fgets(buffer, BUFFERLEN, fp))
01547     {
01548       break;
01549     }
01550     /*
01551        expecting nominal-forward-reverse triplets, e.g.,
01552        0.000000      0.000000      -0.001279
01553        0.100000      0.098742       0.051632
01554        0.200000      0.171529       0.194216
01555     */
01556     if (3 != sscanf(buffer, "%lf %lf %lf", &nom, &fwd, &rev))
01557     {
01558       break;
01559     }
01560     if (index >= EMCMOT_COMP_SIZE)
01561     {
01562       break;
01563     }
01564     emcmotComp[axis]->nominal[index] = nom;
01565     emcmotComp[axis]->forward[index] = fwd;
01566     emcmotComp[axis]->reverse[index] = rev;
01567     index++;
01568     total++;
01569   }
01570   fclose(fp);
01571 
01572   if (total > 1)
01573   {
01574     emcmotComp[axis]->avgint = (emcmotComp[axis]->nominal[total - 1] -
01575                                 emcmotComp[axis]->nominal[0]) / (total - 1);
01576   }
01577 
01578   /* ->total is the flag to emcmot that the comp table is valid, so
01579      only set this to be >1 if the data is really valid: total > 1
01580      and avgint > 0 */
01581   if (total > 1 &&
01582       emcmotComp[axis]->avgint > DBL_MIN)
01583   {
01584     emcmotComp[axis]->total = total;
01585   }
01586   else
01587   {
01588     fprintf(stderr, "compensation file %s has too few distinct points\n", file);
01589     return -1;
01590   }
01591 
01592   /* leave alter alone */
01593 
01594   return 0;
01595 }
01596 
01597 int usrmotAlter(int axis, double alter)
01598 {
01599   /* check axis range */
01600   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
01601   {
01602     fprintf(stderr, "axis out of range for alter\n");
01603     return -1;
01604   }
01605 
01606   /* first check if comp pointer is valid */
01607   if (emcmotComp[axis] == 0)
01608   {
01609     fprintf(stderr, "compensation data structure not present\n");
01610     return -1;
01611   }
01612 
01613   /* set alter value */
01614   emcmotComp[axis]->alter = alter;
01615 
01616   return 0;
01617 }
01618 
01619 int usrmotQueryAlter(int axis, double *alter)
01620 {
01621   /* check axis range */
01622   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
01623   {
01624     fprintf(stderr, "axis out of range for alter query\n");
01625     return -1;
01626   }
01627 
01628   /* first check if comp pointer is valid */
01629   if (emcmotComp[axis] == 0)
01630   {
01631     fprintf(stderr, "compensation data structure not present\n");
01632     return -1;
01633   }
01634 
01635   /* set alter value */
01636   *alter = emcmotComp[axis]->alter;
01637 
01638   return 0;
01639 }
01640 
01641 int usrmotPrintComp(int axis)
01642 {
01643   int t;
01644 
01645   /* check axis range */
01646   if (axis < 0 || axis >= EMCMOT_MAX_AXIS)
01647   {
01648     fprintf(stderr, "axis out of range for compensation\n");
01649     return -1;
01650   }
01651 
01652   /* first check if comp pointer is valid */
01653   if (emcmotComp[axis] == 0)
01654   {
01655     fprintf(stderr, "compensation data structure not present\n");
01656     return -1;
01657   }
01658 
01659   printf("total:  %d\n", emcmotComp[axis]->total);
01660   printf("avgint: %f\n", emcmotComp[axis]->avgint);
01661   printf("alter:  %f\n", emcmotComp[axis]->alter);
01662   for (t = 0; t < emcmotComp[axis]->total; t++)
01663   {
01664     printf("%f\t%f\t%f\n",
01665            emcmotComp[axis]->nominal[t],
01666            emcmotComp[axis]->forward[t],
01667            emcmotComp[axis]->reverse[t]);
01668   }
01669 
01670   return 0;
01671 }

Generated on Sun Dec 2 15:27:44 2001 for EMC by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001