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

emcplot3d.cc

Go to the documentation of this file.
00001 //
00002 // This code was created by Jeff Molofee '99
00003 // (ported to Linux/GLUT by Richard Campbell '99)
00004 //
00005 // If you've found this code useful, please let me know.
00006 //
00007 // Visit Jeff at www.demonews.com/hosted/nehe
00008 // (email Richard Campbell at ulmont@bellsouth.net)
00009 //
00010 #include <GL/glut.h>    // Header File For The GLUT Library
00011 #include <GL/gl.h>      // Header File For The OpenGL32 Library
00012 #include <GL/glu.h>     // Header File For The GLu32 Library
00013 #include <GL/glx.h>     // Header File For The GLu32 Library
00014 #include <stdio.h>      // Header file for standard file i/o.
00015 #include <stdlib.h>     // Header file for malloc/free.
00016 #include <unistd.h>     // needed to sleep.
00017 #include <math.h>
00018 #include <string.h>
00019 
00020 #include "rcs.hh"
00021 #include "emc.hh"
00022 #include "canon.hh"
00023 #include "interpl.hh"
00024 #include "rs274ngc.hh"
00025 
00026 #ifdef NEW_INTERPRETER
00027 #include "rs274ngc_return.hh"
00028 #endif
00029 
00030 
00031 PM_ROTATION_VECTOR view_rv;
00032 
00033 /* note that the message must be a string with a %s in it */
00034 #define DRIVER_ERROR(message,item) if(1)    \
00035    {fprintf(stderr, message, item);         \
00036     fprintf(stderr, "\n");                  \
00037     return RS274NGC_ERROR; }                \
00038    else
00039 
00040 
00041 static RCS_STAT_CHANNEL * emcStatusBuffer = 0;
00042 static RCS_CMD_CHANNEL * emcCommandBuffer = 0;
00043 static RCS_LINKED_LIST *livePlotList = 0;
00044 static RCS_LINKED_LIST *staticPlotList = 0;
00045 static EmcPose last_pose;
00046 static int timer_count=0;
00047 static int showProgrammedPlot = 1;
00048 static int show_stewart_platform = 0;
00049 
00050 struct Point2D
00051 {
00052   double x,y;
00053 };
00054 
00055 struct StewartSpecs {
00056 public:
00057   double plate_height;
00058   Point2D plate_points[6];
00059   double mount_height;
00060   Point2D mount_points[6];
00061   double strut_diameter;
00062   double top_mount_diameter;
00063   double posts_diameter;
00064 };
00065 
00066 
00067 static int refresh_count=5;
00068 static double scale=1.0;
00069 static int timer_period=10;
00070 static int redraw_needed=1;
00071 
00072 
00073 static StewartSpecs stewart_platform_specs;
00074 
00075 void ReadStewartSpecs(const char *filename)
00076 {
00077   stewart_platform_specs.plate_height = 1.0;
00078   for(int i = 0; i< 3; i++)
00079     {
00080       stewart_platform_specs.plate_points[2*i].x = 2.0*cos(2.0*PM_PI/3.0*i - PM_PI/30.0);
00081       stewart_platform_specs.plate_points[2*i].y = 2.0*sin(2.0*PM_PI/3.0*i - PM_PI/30.0);
00082       stewart_platform_specs.plate_points[2*i+1].x = 2.0*cos(2.0*PM_PI/3.0*i + PM_PI/30.0);
00083       stewart_platform_specs.plate_points[2*i+1].y = 2.0*sin(2.*PM_PI/3.0*i + PM_PI/30.0);
00084     }
00085   stewart_platform_specs.mount_height = 1.0;
00086   for(int i = 0; i< 3; i++)
00087     {
00088       stewart_platform_specs.mount_points[2*i+1].x = 10.0*cos(2.0*PM_PI/3.0*i +PM_PI/3.0);
00089       stewart_platform_specs.mount_points[2*i+1].y = 10.0*sin(2.0*PM_PI/3.0*i +PM_PI/3.0);
00090       stewart_platform_specs.mount_points[(2*i+2)%6].x = 10.0*cos(2.0*PM_PI/3.0*i+ PM_PI/3.0);
00091       stewart_platform_specs.mount_points[(2*i+2)%6].y = 10.0*sin(2.0*PM_PI/3.0*i+ PM_PI/3.0);
00092     }
00093 
00094 
00095 
00096 
00097 }
00098 
00099 
00100 
00101 #if 0
00102 extern FILE* _interpreter_fp=NULL;
00103 extern char  _interpreter_linetext[256];
00104 // static char  _interpreter_blocktext[256];
00105 
00106 // NML channels
00107 static RCS_CMD_CHANNEL * emcCommandBuffer = 0;
00108 static NML * emcErrorBuffer = 0;
00109 
00110 // NML command channel data pointer
00111 static RCS_CMD_MSG * emcCommand = 0;
00112 #endif
00113 
00114 // global EMC status
00115 EMC_STAT * emcStatus = 0;
00116 
00117 
00118 /* ascii code for the escape key */
00119 #define ESCAPE 27
00120 
00121 /* The number of our GLUT window */
00122 int window;
00123 
00124 /* storage for one texture  */
00125 GLuint texture[1];
00126 
00127 GLuint plot;             // storage for the display list
00128 GLuint lplot=0;              // storage for the 2nd display list
00129 GLuint plot_rotframes;             // storage for the display list
00130 GLuint lplot_rotframes=0;              // storage for the 2nd display list
00131 GLuint xloop;            // loop for x axis.
00132 GLuint yloop;            // loop for y axis.
00133 
00134 GLfloat xrot=-45.0;            // rotates cube on the x axis.
00135 GLfloat yrot=-45.0;            // rotates cube on the y axis.
00136 GLfloat zrot=-45.0;            // rotates cube on the z axis.
00137 
00138 GLfloat xtran;            // translates cube on the x axis.
00139 GLfloat ytran;            // translates cube on the y axis.
00140 GLfloat ztran;            // translates cube on the z axis.
00141 
00142 int show_plot_rotation_frames = 0;
00143 int showLivePlot = 1;
00144 
00145 
00146 /* Image type - contains height, width, and data */
00147 struct Image {
00148     unsigned long sizeX;
00149     unsigned long sizeY;
00150     char *data;
00151 };
00152 typedef struct Image Image;
00153 
00154 const char *Filename = NULL;
00155 
00156 GLuint base;            // base display list for the font set.
00157 GLfloat cnt1;           // 1st counter used to move text & for coloring.
00158 GLfloat cnt2;           // 2nd counter used to move text & for coloring.
00159 
00160 GLvoid BuildFont(GLvoid)
00161 {
00162     Display *dpy;
00163     XFontStruct *fontInfo;  // storage for our font.
00164 
00165     base = glGenLists(96);                      // storage for 96 characters.
00166 
00167     // load the font.  what fonts any of you have is going
00168     // to be system dependent, but on my system they are
00169     // in /usr/X11R6/lib/X11/fonts/*, with fonts.alias and
00170     // fonts.dir explaining what fonts the .pcf.gz files
00171     // are.  in any case, one of these 2 fonts should be
00172     // on your system...or you won't see any text.
00173 
00174     // get the current display.  This opens a second
00175     // connection to the display in the DISPLAY environment
00176     // value, and will be around only long enough to load
00177     // the font.
00178     dpy = XOpenDisplay(NULL); // default to DISPLAY env.
00179 
00180     fontInfo = XLoadQueryFont(dpy, "-adobe-helvetica-medium-r-normal--18-*-*-*-p-*-iso8859-1");
00181     if (fontInfo == NULL) {
00182         fontInfo = XLoadQueryFont(dpy, "fixed");
00183         if (fontInfo == NULL) {
00184             printf("no X font available?\n");
00185         }
00186     }
00187 
00188     // after loading this font info, this would probably be the time
00189     // to rotate, scale, or otherwise twink your fonts.
00190 
00191     // start at character 32 (space), get 96 characters (a few characters past z), and
00192     // store them starting at base.
00193     glXUseXFont(fontInfo->fid, 32, 96, base);
00194 
00195     // free that font's info now that we've got the
00196     // display lists.
00197     XFreeFont(dpy, fontInfo);
00198 
00199     // close down the 2nd display connection.
00200     XCloseDisplay(dpy);
00201 }
00202 
00203 GLvoid KillFont(GLvoid)                         // delete the font.
00204 {
00205     glDeleteLists(base, 96);                    // delete all 96 characters.
00206 }
00207 
00208 GLvoid glPrint(char *text)                      // custom gl print routine.
00209 {
00210     if (text == NULL) {                         // if there's no text, do nothing.
00211         return;
00212     }
00213 
00214     glPushAttrib(GL_LIST_BIT);                  // alert that we're about to offset the display lists with glListBase
00215     glListBase(base - 32);                      // sets the base character to 32.
00216 
00217     glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // draws the display list text.
00218     glPopAttrib();                              // undoes the glPushAttrib(GL_LIST_BIT);
00219 }
00220 
00221 /*********************************************************************/
00222 
00223 /* interpret_from_file
00224 
00225 Returned Value: (RS274NGC_OK or RS274NGC_ERROR)
00226   If the end of the file has been reached without an m2 or m30
00227   having been read, this returns ENDFILE.
00228   Otherwise, if any of the following errors occur, this returns RS274NGC_ERROR.
00229    Otherwise, it returns RS274NGC_OK.
00230    1. rs274ngc_init returns RS274NGC_ERROR.
00231    2. read_tool_file returns RS274NGC_ERROR.
00232    3. read_setup_file returns RS274NGC_ERROR.
00233    4. rs274ngc_open returns RS274NGC_ERROR.
00234    5. rs274ngc_read returns RS274NGC_ERROR and no_stop is off.
00235    6. rs274ngc_execute returns RS274NGC_ERROR and no_stop is off.
00236    7. fgets is called and returns NULL.
00237 
00238 Side Effects:
00239    An NC-program file is opened, interpreted, and closed.
00240 
00241 Called By:
00242    main
00243 
00244 This emulates the way the EMC system uses the interpreter.
00245 
00246 When this function starts, it prompts the user for the name of a
00247 tool file and then the name of a setup file.  The user may enter a
00248 file name followed by a carriage return or just enter a carriage
00249 return after both prompts. If a file name is entered, the file will be
00250 used. If not, default tool or setup information will be used.
00251 
00252 If the no_stop argument is OFF, this returns if an error is found.
00253 
00254 If the no_stop argument is ON, an error does not stop interpretation.
00255 However, since the file will have been closed, it has to be reopened
00256 and reread up to the next unread line.
00257 
00258 An alternate method of getting back to the right place in a file
00259 would be to use fgetpos and fsetpos.
00260 
00261 */
00262 
00263 int interpret_from_file( /* ARGUMENT VALUES                   */
00264  const char * filename,        /* string: name of the rs274kt file  */
00265  int no_stop)            /* switch which is ON or OFF         */
00266 {
00267   int status;
00268   int reads;
00269   //  char trash[INTERP_TEXT_SIZE];
00270   int program_status;
00271 
00272   program_status SET_TO RS274NGC_OK;
00273   if (rs274ngc_init() ISNT RS274NGC_OK)
00274     {
00275       printf("rs274ngc_init failed.\n");
00276       return -1;
00277     }
00278   if (rs274ngc_open(filename) ISNT RS274NGC_OK)
00279     {
00280       printf("rs274ngc_open(%s) failed.\n",filename);
00281       return -1;
00282     }
00283   for(reads SET_TO 0; ; reads++)
00284     {
00285       interp_list.set_line_number(reads);
00286       status SET_TO rs274ngc_read();
00287       if (status IS RS274NGC_ENDFILE)
00288         return RS274NGC_ENDFILE;
00289       if (status ISNT RS274NGC_OK)
00290         {
00291           printf("rs274ngc_read failed.\n");
00292           return -1;
00293 #if 0
00294         /* should not be RS274NGC_EXIT or RS274NGC_ERROR */
00295           // fprintf(stderr, "%s\n", _interpreter_linetext);
00296           if (no_stop IS OFF)
00297             return RS274NGC_ERROR;
00298           else
00299             {
00300               program_status SET_TO RS274NGC_ERROR;
00301               rs274ngc_open(filename);       /* will have been closed    */
00302               for(k SET_TO -1; k < reads; k++) /* read up to where we were */
00303                 {
00304                   // read_ok SET_TO
00305                   // fgets(trash, INTERP_TEXT_SIZE, _interpreter_fp);
00306                   if (read_ok IS NULL)
00307                     return RS274NGC_ERROR;
00308                 }
00309               continue;
00310             }
00311 #endif
00312         }
00313       status SET_TO rs274ngc_execute(NULL);
00314       if (status ISNT RS274NGC_OK)
00315         {
00316           printf("rs274ngc_execute failed.\n");
00317           return -1;
00318 #if 0
00319           //fprintf(stderr, "%s\n", _interpreter_linetext);
00320           if (no_stop IS OFF)
00321             return RS274NGC_ERROR;
00322           else
00323             {
00324               program_status SET_TO RS274NGC_ERROR;
00325               rs274ngc_open(filename); /* will have been closed */
00326               for(k SET_TO -1; k < reads; k++) /* read up to where we were */
00327                 {
00328                   // read_ok SET_TO
00329                   //  fgets(trash, INTERP_TEXT_SIZE, _interpreter_fp);
00330                   if (read_ok IS NULL)
00331                     return RS274NGC_ERROR;
00332                 }
00333               continue;
00334             }
00335 #endif
00336         }
00337       else if (status IS RS274NGC_EXIT)
00338         return program_status;
00339     }
00340 }
00341 
00342 #define VECTOR_MAG(x,y,z) (sqrt( (x)*(x) + (y)*(y) + (z)*(z)))
00343 
00344 double last_x,last_y, last_z;
00345 
00346 void DoCircularMove(EMC_TRAJ_CIRCULAR_MOVE *cir_move_cmd)
00347 {
00348   int simple = 0;
00349   int axis = 0;
00350 #if 0
00351   printf("DoCircularMove :\n");
00352   printf(" \t end = %f %f %f\n", cir_move_cmd->end.tran.x,
00353          cir_move_cmd->end.tran.y,cir_move_cmd->end.tran.z);
00354   printf(" \t normal = %f %f %f\n", cir_move_cmd->normal.x,
00355          cir_move_cmd->normal.y,cir_move_cmd->normal.z);
00356   printf(" \t center = %f %f %f\n", cir_move_cmd->center.x,
00357          cir_move_cmd->center.y,cir_move_cmd->center.z);
00358   printf(" \t turn = %d\n",cir_move_cmd->turn);
00359   printf(" \t last = %f %f %f\n", last_x, last_y, last_z);
00360 #endif
00361   double axis_diff;
00362   if(cir_move_cmd->normal.x == 0 && cir_move_cmd->normal.y == 0)
00363     {
00364       axis_diff = cir_move_cmd->end.tran.z/emcStatus->motion.traj.linearUnits*scale - last_z;
00365       simple = 1;
00366       axis = 2;
00367     }
00368   else if(cir_move_cmd->normal.x == 0 && cir_move_cmd->normal.z == 0)
00369     {
00370       axis_diff = cir_move_cmd->end.tran.y/emcStatus->motion.traj.linearUnits*scale - last_y;
00371       simple = 1;
00372       axis = 1;
00373     }
00374   else if(cir_move_cmd->normal.y == 0 && cir_move_cmd->normal.z == 0)
00375     {
00376       axis_diff = cir_move_cmd->end.tran.x/emcStatus->motion.traj.linearUnits*scale - last_x;
00377       simple = 1;
00378       axis = 0;
00379     }
00380   if(simple)
00381     {
00382       double r = VECTOR_MAG(cir_move_cmd->end.tran.x - cir_move_cmd->center.x,
00383                             cir_move_cmd->end.tran.y - cir_move_cmd->center.y,
00384                             cir_move_cmd->end.tran.z - cir_move_cmd->center.z)/emcStatus->motion.traj.linearUnits*scale;
00385       double start_angle, sweep_angle;
00386       switch(axis)
00387         {
00388         case 0:
00389           start_angle = atan2( last_z/emcStatus->motion.traj.linearUnits*scale-cir_move_cmd->center.z,
00390                                last_y/emcStatus->motion.traj.linearUnits*scale-cir_move_cmd->center.y);
00391           sweep_angle = atan2( cir_move_cmd->end.tran.z-cir_move_cmd->center.z,
00392                                cir_move_cmd->end.tran.y-cir_move_cmd->center.y);
00393           break;
00394 
00395         case 1:
00396           start_angle = atan2( last_z/emcStatus->motion.traj.linearUnits*scale-cir_move_cmd->center.z,
00397                                last_x/emcStatus->motion.traj.linearUnits*scale-cir_move_cmd->center.x  );
00398           sweep_angle = atan2( cir_move_cmd->end.tran.z-cir_move_cmd->center.z,
00399                                cir_move_cmd->end.tran.x-cir_move_cmd->center.x);
00400           break;
00401 
00402         case 2:
00403           start_angle = atan2( last_y/emcStatus->motion.traj.linearUnits*scale-cir_move_cmd->center.y,
00404                                last_x/emcStatus->motion.traj.linearUnits*scale-cir_move_cmd->center.x);
00405           sweep_angle = atan2( cir_move_cmd->end.tran.y-cir_move_cmd->center.y,
00406                              cir_move_cmd->end.tran.x-cir_move_cmd->center.x);
00407           break;
00408         }
00409       double angle_increment = 0.01;
00410       double angle = start_angle;
00411       double angle_diff = fabs(angle - sweep_angle);
00412       angle_increment = (cir_move_cmd->turn < 0)?-0.01:+0.01;
00413       double axis_increment = fabs(angle_increment/angle_diff)*axis_diff;
00414       int i = 0;
00415       double x,y,z;
00416       x = last_x;
00417       y = last_y;
00418       z = last_z;
00419       for(;  i <  3 || angle_diff > 1.5*fabs(angle_increment); angle += angle_increment)
00420       {
00421         i++;
00422         //printf("angle_diff = %f\n",angle_diff);
00423         angle_diff = fabs(angle - sweep_angle);
00424         if(angle_diff > 2*PM_PI)
00425         {
00426           angle_diff -= 2*PM_PI;
00427         }
00428         switch(axis)
00429           {
00430           case 0:
00431             x += axis_increment;
00432             y = cir_move_cmd->center.y/emcStatus->motion.traj.linearUnits*scale + cos(angle)*r;
00433             z = cir_move_cmd->center.z/emcStatus->motion.traj.linearUnits*scale + sin(angle)*r;
00434             break;
00435 
00436           case 1:
00437             y += axis_increment;
00438             x = cir_move_cmd->center.x/emcStatus->motion.traj.linearUnits*scale + cos(angle)*r;
00439             z = cir_move_cmd->center.z/emcStatus->motion.traj.linearUnits*scale + sin(angle)*r;
00440             break;
00441 
00442           case 2:
00443             z += axis_increment;
00444             x = cir_move_cmd->center.x/emcStatus->motion.traj.linearUnits*scale + cos(angle)*r;
00445             y = cir_move_cmd->center.y/emcStatus->motion.traj.linearUnits*scale + sin(angle)*r;
00446             break;
00447           }
00448         //printf("angle=%f, vertex = %f %f %f\n",angle,x,y,z);
00449         glVertex3f(x,y,z);
00450       }
00451     }
00452   else
00453     {
00454       printf("Circular moves not aligned with an axis are not supported.\n");
00455     }
00456   glVertex3f(last_x = cir_move_cmd->end.tran.x/emcStatus->motion.traj.linearUnits*scale,
00457              last_y = cir_move_cmd->end.tran.y/emcStatus->motion.traj.linearUnits*scale,
00458              last_z = cir_move_cmd->end.tran.z/emcStatus->motion.traj.linearUnits*scale);
00459 }
00460 
00461 
00462 GLvoid RebuildLivePlot()
00463 {
00464   GLuint lplot_temp;
00465   GLuint lplot_rotframes_temp;
00466   lplot_temp = lplot;
00467   lplot_rotframes_temp=lplot_rotframes_temp;
00468   lplot=0;
00469   lplot_rotframes=0;
00470   if(0 != lplot_temp)
00471     {
00472       glDeleteLists(lplot_temp,1);
00473       lplot_temp = 0;
00474     }
00475   if(0 != lplot_rotframes_temp)
00476     {
00477       glDeleteLists(lplot_rotframes_temp,1);
00478       lplot_rotframes_temp = 0;
00479     }
00480   lplot_temp = glGenLists(1);
00481   glNewList(lplot_temp, GL_COMPILE);
00482 
00483   glColor3f(0.0,0.0,1.0);
00484   glBegin(GL_LINE_STRIP);
00485 
00486 
00487   EmcPose *emcPose = (EmcPose *) livePlotList->get_head();
00488   while(NULL != emcPose)
00489     {
00490       glVertex3f(emcPose->tran.x/emcStatus->motion.traj.linearUnits*scale,
00491                  emcPose->tran.y/emcStatus->motion.traj.linearUnits*scale,
00492                  emcPose->tran.z/emcStatus->motion.traj.linearUnits*scale);
00493       emcPose = (EmcPose *) livePlotList->get_next();
00494     }
00495   glEnd();
00496   glEndList();
00497 
00498 
00499   lplot_rotframes_temp = glGenLists(1); 
00500   // generate storage for 1 lists, and return a pointer to the first.
00501 
00502   glNewList(lplot_rotframes_temp, GL_COMPILE);
00503 
00504   EmcPose last_p;
00505   EmcPose *p = (EmcPose *) livePlotList->get_head();
00506   while(p != NULL)
00507     {
00508       if(
00509          fabs(last_p.tran.x - p->tran.x) >= 0.01*emcStatus->motion.traj.linearUnits/scale ||
00510          fabs(last_p.tran.y - p->tran.y) >= 0.01*emcStatus->motion.traj.linearUnits/scale ||
00511          fabs(last_p.tran.z - p->tran.z) >= 0.01*emcStatus->motion.traj.linearUnits/scale ||
00512          fabs(last_p.a - p->a) >= 0.1 ||
00513          fabs(last_p.b - p->b) >= 0.1 ||
00514          fabs(last_p.c - p->c) >= 0.1 )
00515         {
00516           PM_RPY rpy(p->a*PM_PI/180.0,p->b*PM_PI/180.0,p->c*PM_PI/180.0);
00517           PM_ROTATION_VECTOR rv(rpy);
00518           glTranslatef(p->tran.x/emcStatus->motion.traj.linearUnits*scale,
00519                        p->tran.y/emcStatus->motion.traj.linearUnits*scale,
00520                        p->tran.z/emcStatus->motion.traj.linearUnits*scale);
00521           glRotatef(rv.s*180.0/PM_PI,rv.x,rv.y,rv.z);
00522           
00523           // Axis Lines.
00524           glBegin(GL_LINES);
00525           glColor3f(0.4f,1.0f,0.4f);
00526           glVertex3f(0.6f,0.0f,0.0f);
00527           glVertex3f(0.0,0.0,0.0f);
00528           glColor3f(1.0f,0.4f,0.4f);
00529           glVertex3f(0.0,0.0,0.0);
00530           glVertex3f(0.0,0.6,0.0);
00531           glColor3f(0.4f,0.4f,1.0f);
00532           glVertex3f(0.0,0.0,0.0);
00533           glVertex3f(0.0,0.0,0.6);
00534           glEnd();
00535 
00536           glRotatef(-rv.s*180.0/PM_PI,rv.x,rv.y,rv.z);
00537           glTranslatef(-p->tran.x/emcStatus->motion.traj.linearUnits*scale,
00538                    -p->tran.y/emcStatus->motion.traj.linearUnits*scale,
00539                    -p->tran.z/emcStatus->motion.traj.linearUnits*scale);
00540           last_p = *p;
00541         }
00542       p = (EmcPose *) livePlotList->get_next();
00543     }
00544   glEndList();
00545 
00546   lplot = lplot_temp;
00547   lplot_rotframes=lplot_rotframes_temp;
00548 }
00549 
00550 
00551 GLvoid BuildDataPlot()
00552 {
00553 
00554   FILE *f=stdin;
00555 
00556   if(Filename != NULL)
00557     {
00558       if(Filename[0] != 0)
00559         {
00560           f = fopen(Filename,"r");
00561         }
00562     }
00563   char buf[256];
00564 
00565   if(NULL != staticPlotList)
00566     {
00567       delete staticPlotList;
00568       staticPlotList = NULL;
00569     }
00570   staticPlotList = new RCS_LINKED_LIST();
00571 
00572   while(!feof(f))
00573     {
00574       fgets(buf,256,f);
00575       double x,y,z,a,b,c;
00576       x = y = z = a = b = c = 0.0;
00577       if(sscanf(buf,"%lf %lf %lf %lf %lf %lf", &x,&y,&z,&a,&b,&c) < 3)
00578         {
00579           break;
00580         }
00581       EmcPose pose;
00582       pose.tran.x = x;
00583       pose.tran.y = y;
00584       pose.tran.z = z;
00585       pose.a = a;
00586       pose.b = b;
00587       pose.c = c;
00588       staticPlotList->store_at_tail(&pose,sizeof(EmcPose),1);
00589     }
00590   if(f != stdin)
00591     {
00592       fclose(f);
00593     }
00594 
00595   plot_rotframes = glGenLists(1);              // generate storage for 2 lists, and return a pointer to the first.
00596 
00597   glNewList(plot_rotframes, GL_COMPILE);
00598 
00599   EmcPose *p = (EmcPose *) staticPlotList->get_head();
00600   while(p != NULL)
00601     {
00602       PM_RPY rpy(p->a*PM_PI/180.0,p->b*PM_PI/180.0,p->c*PM_PI/180.0);
00603       PM_ROTATION_VECTOR rv(rpy);
00604       glTranslatef(p->tran.x/emcStatus->motion.traj.linearUnits*scale,
00605                    p->tran.y/emcStatus->motion.traj.linearUnits*scale,
00606                    p->tran.z/emcStatus->motion.traj.linearUnits*scale);
00607       glRotatef(rv.s*180.0/PM_PI,rv.x,rv.y,rv.z);
00608 
00609       // Axis Lines.
00610       glBegin(GL_LINES);
00611       glColor3f(0.2f,1.0f,0.2f);
00612       glVertex3f(0.5f,0.0f,0.0f);
00613       glVertex3f(0.0,0.0,0.0f);
00614       glColor3f(1.0f,0.2f,0.2f);
00615       glVertex3f(0.0,0.0,0.0);
00616       glVertex3f(0.0,0.5,0.0);
00617       glColor3f(0.2f,0.2f,1.0f);
00618       glVertex3f(0.0,0.0,0.0);
00619       glVertex3f(0.0,0.0,0.5);
00620       glEnd();
00621 
00622       glRotatef(-rv.s*180.0/PM_PI,rv.x,rv.y,rv.z);
00623       glTranslatef(-p->tran.x/emcStatus->motion.traj.linearUnits*scale,
00624                    -p->tran.y/emcStatus->motion.traj.linearUnits*scale,
00625                    -p->tran.z/emcStatus->motion.traj.linearUnits*scale);
00626       p = (EmcPose *) staticPlotList->get_next();
00627     }
00628   glEndList();
00629 
00630   plot = glGenLists(1);    
00631   // generate storage for 2 lists, and return a pointer to the first.
00632 
00633   glNewList(plot, GL_COMPILE);
00634 
00635   glColor3f(1.0,1.0,1.0f);
00636   glBegin(GL_LINE_STRIP);
00637 
00638   p = (EmcPose *) staticPlotList->get_head();
00639   while(p != NULL)
00640     {
00641       glVertex3f(p->tran.x/emcStatus->motion.traj.linearUnits*scale,
00642                  p->tran.y/emcStatus->motion.traj.linearUnits*scale,
00643                  p->tran.z/emcStatus->motion.traj.linearUnits*scale);
00644       p = (EmcPose *) staticPlotList->get_next();
00645     }
00646   glEnd();
00647   glEndList();
00648 }
00649 
00650 
00651 
00652 
00653 // build the display list.
00654 GLvoid BuildList()
00655 {
00656   NMLmsg *cmd;
00657   //  GLUquadric* quad = gluNewQuadric();
00658 
00659    if(NULL == Filename)
00660      {
00661        BuildDataPlot();
00662        return;
00663      }
00664 
00665    if(NULL != strstr(Filename,".data"))
00666    {
00667      BuildDataPlot();
00668      return;
00669    }
00670 
00671   
00672   if(NULL != Filename)
00673     {
00674       if(!strncmp(Filename, "NULL",4) || 
00675          !strncmp(Filename,"null",4))
00676         {
00677           Filename = NULL;
00678           return;
00679         }
00680     }
00681 
00682   if(NULL == Filename)
00683     {
00684       return;
00685     }
00686 
00687    plot = glGenLists(1);              // generate storage for 2 lists, and return a pointer to the first.
00688 
00689    interpret_from_file(Filename, 1);
00690 
00691    glNewList(plot, GL_COMPILE);       // store this list at location cube, and compile it once.
00692 
00693     last_x=0.0;
00694     last_y=0.0;
00695     last_z=0.0;
00696 
00697     glColor3f(1.0f,1.0f,1.0f);
00698     glBegin(GL_LINE_STRIP);
00699     while( (cmd = interp_list.get()) > 0)
00700       {
00701         printf("%d : %s : (%s)\n",interp_list.get_line_number(),
00702                emcSymbolLookup(cmd->type),(emcCommandBuffer!=0?emcCommandBuffer->msg2str(cmd):" ")); 
00703         switch(cmd->type)
00704           {
00705           case EMC_TRAJ_LINEAR_MOVE_TYPE:
00706             {
00707               EMC_TRAJ_LINEAR_MOVE *lin_move_cmd = (EMC_TRAJ_LINEAR_MOVE *) cmd;
00708               glVertex3f(last_x = lin_move_cmd->end.tran.x/emcStatus->motion.traj.linearUnits*scale,
00709                          last_y = lin_move_cmd->end.tran.y/emcStatus->motion.traj.linearUnits*scale,
00710                          last_z = lin_move_cmd->end.tran.z/emcStatus->motion.traj.linearUnits*scale);
00711             }
00712             break;
00713 
00714           case EMC_TRAJ_CIRCULAR_MOVE_TYPE:
00715             {
00716               EMC_TRAJ_CIRCULAR_MOVE *cir_move_cmd = (EMC_TRAJ_CIRCULAR_MOVE *) cmd;
00717               DoCircularMove(cir_move_cmd);
00718             }
00719             break;
00720 
00721           case EMC_TRAJ_SET_VELOCITY_TYPE:
00722           case EMC_TRAJ_SET_ACCELERATION_TYPE:
00723             break;
00724 
00725 
00726           default:
00727             //printf("Unrecognized cmd->type = %d\n",cmd->type);
00728             break;
00729           }
00730       }
00731     glEnd();
00732     glEndList();
00733 
00734 
00735     
00736     interpret_from_file(Filename, 1);
00737 
00738    plot_rotframes = glGenLists(1);
00739    
00740    glNewList(plot_rotframes, GL_COMPILE);       // store this list at location cube, and compile it once.
00741 
00742     last_x=0.0;
00743     last_y=0.0;
00744     last_z=0.0;
00745 
00746     
00747     while( (cmd = interp_list.get()) > 0)
00748       {
00749         printf("%d : %s : (%s)\n",interp_list.get_line_number(),
00750                emcSymbolLookup(cmd->type),(emcCommandBuffer!=0?emcCommandBuffer->msg2str(cmd):" ")); 
00751         switch(cmd->type)
00752           {
00753           case EMC_TRAJ_LINEAR_MOVE_TYPE:
00754             {
00755               EMC_TRAJ_LINEAR_MOVE *lin_move_cmd = (EMC_TRAJ_LINEAR_MOVE *) cmd;
00756               PM_RPY rpy(lin_move_cmd->end.a*PM_PI/180.0,lin_move_cmd->end.b*PM_PI/180.0,lin_move_cmd->end.c*PM_PI/180.0);
00757               PM_ROTATION_VECTOR rv(rpy);
00758               glTranslatef(lin_move_cmd->end.tran.x/emcStatus->motion.traj.linearUnits*scale,
00759                            lin_move_cmd->end.tran.y/emcStatus->motion.traj.linearUnits*scale,
00760                            lin_move_cmd->end.tran.z/emcStatus->motion.traj.linearUnits*scale);
00761               glRotatef(rv.s*180.0/PM_PI,rv.x,rv.y,rv.z);
00762                   
00763               // Axis Lines.
00764               glBegin(GL_LINES);
00765               glColor3f(0.2f,1.0f,0.2f);
00766               glVertex3f(0.5f,0.0f,0.0f);
00767               glVertex3f(0.0,0.0,0.0f);
00768               glColor3f(1.0f,0.2f,0.2f);
00769               glVertex3f(0.0,0.0,0.0);
00770               glVertex3f(0.0,0.5,0.0);
00771               glColor3f(0.2f,0.2f,1.0f);
00772               glVertex3f(0.0,0.0,0.0);
00773               glVertex3f(0.0,0.0,0.5);
00774               glEnd();
00775                   
00776               glRotatef(-rv.s*180.0/PM_PI,rv.x,rv.y,rv.z);
00777               glTranslatef(-lin_move_cmd->end.tran.x/emcStatus->motion.traj.linearUnits*scale,
00778                            -lin_move_cmd->end.tran.y/emcStatus->motion.traj.linearUnits*scale,
00779                            -lin_move_cmd->end.tran.z/emcStatus->motion.traj.linearUnits*scale);
00780             }
00781             break;
00782 
00783 
00784           case EMC_TRAJ_SET_VELOCITY_TYPE:
00785           case EMC_TRAJ_SET_ACCELERATION_TYPE:
00786             break;
00787 
00788 
00789           default:
00790             //printf("Unrecognized cmd->type = %d\n",cmd->type);
00791             break;
00792           }
00793       }
00794     glEnd();
00795     glEndList();
00796 }
00797 
00798 #if 0
00799 
00800 
00801 // quick and dirty bitmap loader...for 24 bit bitmaps with 1 plane only.
00802 // See http://www.dcs.ed.ac.uk/~mxr/gfx/2d/BMP.txt for more info.
00803 int ImageLoad(char *filename, Image *image) {
00804     FILE *file;
00805     unsigned long size;                 // size of the image in bytes.
00806     unsigned long i;                    // standard counter.
00807     unsigned short int planes;          // number of planes in image (must be 1)
00808     unsigned short int bpp;             // number of bits per pixel (must be 24)
00809     char temp;                          // temporary color storage for bgr-rgb conversion.
00810 
00811     // make sure the file is there.
00812     if ((file = fopen(filename, "rb"))==NULL)
00813     {
00814         printf("File Not Found : %s\n",filename);
00815         return 0;
00816     }
00817 
00818     // seek through the bmp header, up to the width/height:
00819     fseek(file, 18, SEEK_CUR);
00820 
00821     // read the width
00822     if ((i = fread(&image->sizeX, 4, 1, file)) != 1) {
00823         printf("Error reading width from %s.\n", filename);
00824         return 0;
00825     }
00826     printf("Width of %s: %lu\n", filename, image->sizeX);
00827 
00828     // read the height
00829     if ((i = fread(&image->sizeY, 4, 1, file)) != 1) {
00830         printf("Error reading height from %s.\n", filename);
00831         return 0;
00832     }
00833     printf("Height of %s: %lu\n", filename, image->sizeY);
00834 
00835     // calculate the size (assuming 24 bits or 3 bytes per pixel).
00836     size = image->sizeX * image->sizeY * 3;
00837 
00838     // read the planes
00839     if ((fread(&planes, 2, 1, file)) != 1) {
00840         printf("Error reading planes from %s.\n", filename);
00841         return 0;
00842     }
00843     if (planes != 1) {
00844         printf("Planes from %s is not 1: %u\n", filename, planes);
00845         return 0;
00846     }
00847 
00848     // read the bpp
00849     if ((i = fread(&bpp, 2, 1, file)) != 1) {
00850         printf("Error reading bpp from %s.\n", filename);
00851         return 0;
00852     }
00853     if (bpp != 24) {
00854         printf("Bpp from %s is not 24: %u\n", filename, bpp);
00855         return 0;
00856     }
00857 
00858     // seek past the rest of the bitmap header.
00859     fseek(file, 24, SEEK_CUR);
00860 
00861     // read the data.
00862     image->data = (char *) malloc(size);
00863     if (image->data == NULL) {
00864         printf("Error allocating memory for color-corrected image data");
00865         return 0;
00866     }
00867 
00868     if ((i = fread(image->data, size, 1, file)) != 1) {
00869         printf("Error reading image data from %s.\n", filename);
00870         return 0;
00871     }
00872 
00873     for (i=0;i<size;i+=3) { // reverse all of the colors. (bgr -> rgb)
00874         temp = image->data[i];
00875         image->data[i] = image->data[i+2];
00876         image->data[i+2] = temp;
00877     }
00878 
00879     // we're done.
00880     return 1;
00881 }
00882 
00883 // Load Bitmaps And Convert To Textures
00884 void LoadGLTextures() {
00885     // Load Texture
00886     Image *image1;
00887 
00888     // allocate space for texture
00889     image1 = (Image *) malloc(sizeof(Image));
00890     if (image1 == NULL) {
00891         printf("Error allocating space for image");
00892         exit(0);
00893     }
00894 
00895     if (!ImageLoad("Data/lesson12/cube.bmp", image1)) {
00896         exit(1);
00897     }
00898 
00899     // Create Texture
00900     glGenTextures(1, &texture[0]);
00901     glBindTexture(GL_TEXTURE_2D, texture[0]);   // 2d texture (x and y size)
00902 
00903     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // scale linearly when image bigger than texture
00904     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); // scale linearly (use mipmaps) when image smaller than texture
00905 
00906     // 2d texture, 3 components (red, green, blue), x size from image, y size from image,
00907     // rgb color data, unsigned byte data, and finally the data itself.
00908     gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image1->sizeX, image1->sizeY, GL_RGB, GL_UNSIGNED_BYTE, image1->data);
00909 };
00910 #endif
00911 
00912 GLUquadric *quad = 0;
00913 
00914 /* A general OpenGL initialization function.  Sets all of the initial parameters. */
00915 void InitGL(int Width, int Height)
00916 {
00917   PM_RPY rpy_zero(-PM_PI/4.0,-PM_PI/4.0,-PM_PI/4.0);
00918   PM_ROTATION_VECTOR rv_zero(rpy_zero);
00919   view_rv = rv_zero;
00920 #if 0
00921     LoadGLTextures();                           // Load The Texture(s)
00922 #endif
00923     quad = gluNewQuadric();
00924     BuildList();                                // set up our display lists.
00925     glEnable(GL_TEXTURE_2D);                    // Enable Texture Mapping
00926 
00927     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);       // Clear The Background Color To Blue
00928     glClearDepth(1.0);                          // Enables Clearing Of The Depth Buffer
00929     glDepthFunc(GL_LESS);                       // The Type Of Depth Test To Do
00930     glEnable(GL_DEPTH_TEST);                    // Enables Depth Testing
00931     glShadeModel(GL_SMOOTH);                    // Enables Smooth Color Shading
00932 
00933     glMatrixMode(GL_PROJECTION);
00934     glLoadIdentity();                           // Reset The Projection Matrix
00935 
00936     gluPerspective(30.0f,(GLfloat)Width/(GLfloat)Height,0.1f,1000.0f);  // Calculate The Aspect Ratio Of The Window
00937 
00938     glMatrixMode(GL_MODELVIEW);
00939 
00940     //glEnable(GL_LIGHT0);
00941     //glEnable(GL_LIGHTING);
00942     glEnable(GL_COLOR_MATERIAL);
00943     BuildFont();
00944 }
00945 
00946 /* The function called when our window is resized (which shouldn't happen, because we're fullscreen) */
00947 void ReSizeGLScene(int Width, int Height)
00948 {
00949     if (Height==0)                              // Prevent A Divide By Zero If The Window Is Too Small
00950         Height=1;
00951 
00952     glViewport(0, 0, Width, Height);            // Reset The Current Viewport And Perspective Transformation
00953 
00954     glMatrixMode(GL_PROJECTION);
00955     glLoadIdentity();
00956 
00957     gluPerspective(30.0f,(GLfloat)Width/(GLfloat)Height,0.1f,1000.0f);
00958     glMatrixMode(GL_MODELVIEW);
00959 }
00960 
00961 /* The main drawing function. */
00962 void DrawGLScene()
00963 {
00964   if(!redraw_needed)
00965     {
00966       return;
00967     }
00968   redraw_needed=0;
00969 
00970 
00971     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);         // Clear The Screen And The Depth Buffer
00972 
00973     //    glBindTexture(GL_TEXTURE_2D, texture[0]);
00974     //printf(" %f %f %f  %f %f %f\n", xtran, ytran, ztran,xrot,yrot,zrot);
00975 
00976     glLoadIdentity();
00977 
00978     char buf[256];
00979     glTranslatef(0.0,0.0,-30.0);
00980     PM_QUATERNION view_quat(view_rv);
00981     PM_RPY view_rpy(view_quat);
00982   // Position The Text On The Screen
00983     glColor3f(1.0,0.0,0.0);
00984     glRasterPos2f(-7.0,7.0);
00985     sprintf(buf,"View Offset -- (X=%2.2f,Y=%2.2f,Z=%2.2f, Roll=%2.2f, Pitch=%2.2f, Yaw=%2.2f)",
00986             xtran,ytran,ztran-30,view_rpy.r*180.0/PM_PI,view_rpy.p*180.0/PM_PI,view_rpy.y*180.0/PM_PI);
00987     glPrint(buf);
00988     glRasterPos2f(-7.0,6.5);
00989     sprintf(buf,"EMC Position -- (X=%2.2f,Y=%2.2f,Z=%2.2f, A=%2.2f, B=%2.2f, C=%2.2f)",
00990             last_pose.tran.x,last_pose.tran.y,last_pose.tran.z,
00991             last_pose.a, last_pose.b, last_pose.c);
00992     glPrint(buf);
00993     if(NULL != Filename)
00994       {
00995         glRasterPos2f(-7.0,6.0);
00996         sprintf(buf,"Program File: %s",Filename);
00997         glPrint(buf);
00998       }
00999 
01000     PM_RPY rpy(xrot*PM_PI/180.0, yrot*PM_PI/180.0, zrot*PM_PI/180);
01001     PM_ROTATION_VECTOR rv(rpy);
01002     glTranslatef(xtran,ytran,ztran);
01003 
01004     //glRotatef(zrot,0.0,0.0,1.0);
01005     //glRotatef(yrot,0.0,1.0,0.0);
01006     //glRotatef(xrot,1.0,0.0,0.0);
01007 
01008 #if 0
01009         glBegin(GL_LINES);
01010         glColor3f(1.0,0.0,1.0);
01011         glVertex3f(0.0,0.0,0.0);
01012         glVertex3f(2*rv.x,2*rv.y,2*rv.z);
01013         glEnd();
01014         glColor3f(0.0,1.0,1.0);
01015         gluCylinder(quad, 0.01f, rv.s, 1.1f,100, 10);
01016 #endif
01017 
01018 
01019         glRotatef(view_rv.s*180/PM_PI,view_rv.x,view_rv.y,view_rv.z);
01020 
01021     // Axis Lines.
01022     glBegin(GL_LINES);
01023     glColor3f(0.2f,1.0f,0.2f);
01024     glVertex3f(10.0f,0.0f,0.0f);
01025     glVertex3f(0.0,0.0,0.0f);
01026     glColor3f(1.0f,0.2f,0.2f);
01027     glVertex3f(0.0,0.0,0.0);
01028     glVertex3f(0.0,10.0,0.0);
01029     glColor3f(0.2f,0.2f,1.0f);
01030     glVertex3f(0.0,0.0,0.0);
01031     glVertex3f(0.0,0.0,10.0);
01032     glEnd();
01033 
01034 
01035     //glColor3fv(boxcol[yloop-1]);
01036     if(lplot != 0 && showLivePlot)
01037       {
01038         glCallList(lplot);
01039         if(show_plot_rotation_frames&2)
01040           {
01041             glCallList(lplot_rotframes);
01042           }
01043       }
01044     if(showProgrammedPlot && plot)
01045       {
01046         glCallList(plot);
01047         if(show_plot_rotation_frames&1)
01048           {
01049             glCallList(plot_rotframes);
01050           }
01051       }
01052 
01053 
01054     PM_RPY rpy2(last_pose.a*PM_PI/180.0,last_pose.b*PM_PI/180.0,last_pose.c*PM_PI/180.0);
01055     PM_ROTATION_VECTOR rv2(rpy2);
01056     glTranslatef(last_pose.tran.x/emcStatus->motion.traj.linearUnits*scale,
01057                  last_pose.tran.y/emcStatus->motion.traj.linearUnits*scale,
01058                  last_pose.tran.z/emcStatus->motion.traj.linearUnits*scale);
01059     glRotatef(rv2.s*180.0/PM_PI,rv2.x,rv2.y,rv2.z);
01060 
01061     if(1)
01062     {
01063       // Axis Lines.
01064       glBegin(GL_LINES);
01065       glColor3f(0.4f,1.0f,0.4f);
01066       glVertex3f(0.6f,0.0f,0.0f);
01067       glVertex3f(0.0,0.0,0.0f);
01068       glColor3f(1.0f,0.4f,0.4f);
01069       glVertex3f(0.0,0.0,0.0);
01070       glVertex3f(0.0,0.6,0.0);
01071       glColor3f(0.4f,0.4f,1.0f);
01072       glVertex3f(0.0,0.0,0.0);
01073       glVertex3f(0.0,0.0,0.6);
01074       glEnd();
01075       
01076       glColor3f(0.5,0.5,0.5);
01077       gluCylinder(quad, 
01078                   0.01f,
01079                   0.05f, 
01080                   1.1,
01081                   100, 
01082                   10);
01083     }
01084     glRotatef(-rv2.s*180.0/PM_PI,rv2.x,rv2.y,rv2.z);
01085     glTranslatef(-last_pose.tran.x/emcStatus->motion.traj.linearUnits*scale,
01086                  -last_pose.tran.y/emcStatus->motion.traj.linearUnits*scale,
01087                  -last_pose.tran.z/emcStatus->motion.traj.linearUnits*scale);
01088 
01089     if(show_stewart_platform)
01090       {
01091         glEnable(GL_BLEND);
01092         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
01093         glColor4f(1.0,0.0,0.0,0.75);
01094         glBegin(GL_POLYGON);
01095         for(int i = 0; i < 6; i++)
01096           {
01097             glVertex3f(stewart_platform_specs.plate_points[i].x,
01098                        stewart_platform_specs.plate_points[i].y,
01099                        1.0);
01100           }
01101         glEnd();
01102         glDisable(GL_BLEND);
01103         glTranslatef(-last_pose.tran.x,-last_pose.tran.y,-last_pose.tran.z);
01104         glColor4f(0.0,1.0,1.0,1.0);
01105         glBegin(GL_LINES);
01106         for(int i = 0; i < 6; i++)
01107           {
01108             glVertex3f(stewart_platform_specs.plate_points[i].x+last_pose.tran.x,
01109                        stewart_platform_specs.plate_points[i].y+last_pose.tran.y,
01110                        1.0+last_pose.tran.z);
01111             glVertex3f(stewart_platform_specs.mount_points[i].x,
01112                        stewart_platform_specs.mount_points[i].y,
01113                        10.0);
01114           }
01115         glEnd();
01116       }
01117 
01118  // since this is double buffered, swap the buffers to display what just got drawn.
01119     glutSwapBuffers();
01120 }
01121 
01122 /* The function called whenever a key is pressed. */
01123 void keyPressed(unsigned char key, int x, int y)
01124 {
01125     /* If escape is pressed, kill everything. */
01126     if (key == ESCAPE)
01127     {
01128         /* shut down our window */
01129         glutDestroyWindow(window);
01130 
01131       /* exit the program...normal termination. */
01132         exit(0);
01133     }
01134     else if(key == ' ')
01135       {
01136         PM_RPY rpytemp(-PM_PI/4.0,-PM_PI/4.0,-PM_PI/4.0);
01137         PM_ROTATION_VECTOR rvtemp(rpytemp);
01138         view_rv = rvtemp;
01139         xtran = 0.0;
01140         ytran = 0.0;
01141         ztran = 0.0;
01142         xrot = -45.0;
01143         yrot = -45.0;
01144         zrot = -45.0;
01145       }
01146     else if(key == 'x' || key == 'X')
01147       {
01148         PM_RPY rpytemp(-PM_PI/2.0,-PM_PI/2.0,0.0);
01149         PM_ROTATION_VECTOR rvtemp(rpytemp);
01150         view_rv = rvtemp;
01151       }
01152     else if(key == 'y' || key == 'Y')
01153       {
01154         PM_RPY rpytemp(-PM_PI/2.0,0.0,0.0);
01155         PM_ROTATION_VECTOR rvtemp(rpytemp);
01156         view_rv = rvtemp;
01157       }
01158     else if(key == 'z' || key == 'Z')
01159       {
01160         PM_RPY rpytemp(0.0,0.0,0.0);
01161         PM_ROTATION_VECTOR rvtemp(rpytemp);
01162         view_rv = rvtemp;
01163       }
01164     else if(key == 'k' || key == 'K')
01165       {
01166         PM_RPY rpytemp(-PM_PI/4.0,-PM_PI/4.0,-PM_PI/4.0);
01167         PM_ROTATION_VECTOR rvtemp(rpytemp);
01168         view_rv = rvtemp;
01169       }
01170     else if(key == 'c' || key == 'C')
01171       {
01172         if(NULL != livePlotList)
01173           {
01174             delete livePlotList;
01175             livePlotList = new RCS_LINKED_LIST;
01176           }
01177         RebuildLivePlot();
01178       }
01179     else if(key == 'p' || key == 'P')
01180       {
01181         showProgrammedPlot = !showProgrammedPlot;
01182       }
01183     else if(key == 's' || key == 'S')
01184       {
01185         show_stewart_platform = !show_stewart_platform;
01186       }
01187     else if(key == 'r' || key == 'R')
01188       {
01189         show_plot_rotation_frames++;
01190         show_plot_rotation_frames %=4;
01191       }
01192     else if(key == 'l' || key == 'L')
01193       {
01194         showLivePlot = !showLivePlot;
01195       }
01196     redraw_needed=1;
01197     glutPostRedisplay();
01198 }
01199 
01200 /* The function called whenever a normal key is pressed. */
01201 void specialKeyPressed(int key, int x, int y)
01202 {
01203   int modifiers;
01204 
01205   modifiers = glutGetModifiers();
01206   if(modifiers & GLUT_ACTIVE_SHIFT)
01207     {
01208       PM_QUATERNION view_quat(view_rv);
01209       switch (key) {
01210       case GLUT_KEY_UP:
01211         {
01212           PM_ROTATION_VECTOR rv_up(2.0*PM_PI/180,0.0,1.0,0.0);
01213           PM_QUATERNION quat_up(rv_up);
01214           view_rv = view_quat *quat_up;
01215         }
01216         break;
01217 
01218       case GLUT_KEY_DOWN:
01219         {
01220           PM_ROTATION_VECTOR rv_down(-2.0*PM_PI/180,0.0,1.0,0.0);
01221           PM_QUATERNION quat_down(rv_down);
01222           view_rv = view_quat *quat_down;
01223         }
01224         break;
01225 
01226       case GLUT_KEY_LEFT:
01227         {
01228           PM_ROTATION_VECTOR rv_left(-2.0*PM_PI/180,1.0,0.0,0.0);
01229           PM_QUATERNION quat_left(rv_left);
01230           view_rv = view_quat *quat_left;
01231         }
01232         break;
01233 
01234       case GLUT_KEY_RIGHT:
01235         {
01236           PM_ROTATION_VECTOR rv_right(2.0*PM_PI/180,1.0,0.0,0.0);
01237           PM_QUATERNION quat_right(rv_right);
01238           view_rv = view_quat *quat_right;
01239         }
01240         break;
01241 
01242       case GLUT_KEY_PAGE_UP:
01243         {
01244           PM_ROTATION_VECTOR rv_zup(2.0*PM_PI/180,0.0,0.0,1.0);
01245           PM_QUATERNION quat_zup(rv_zup);
01246           view_rv = view_quat *quat_zup;
01247         }
01248         break;
01249 
01250       case GLUT_KEY_PAGE_DOWN:
01251         {
01252           PM_ROTATION_VECTOR rv_zdown(-2.0*PM_PI/180,0.0,0.0,1.0);
01253           PM_QUATERNION quat_zdown(rv_zdown);
01254           view_rv = view_quat *quat_zdown;
01255         }
01256         break;
01257 
01258       default:
01259         printf ("Special key %d pressed. No action there yet.\n", key);
01260         break;
01261       }
01262       /*  printf("view_rv : %f %f %f %f\n",
01263           view_rv.s, view_rv.x, view_rv.y,view_rv.z); */
01264    }
01265   else
01266     {
01267       switch (key) {
01268       case GLUT_KEY_UP:
01269         ytran += 0.2f;
01270         break;
01271 
01272       case GLUT_KEY_DOWN:
01273         ytran -= 0.2f;
01274         break;
01275 
01276       case GLUT_KEY_LEFT:
01277         xtran -= 0.2f;
01278         break;
01279 
01280       case GLUT_KEY_RIGHT:
01281         xtran += 0.2f;
01282         break;
01283 
01284       case GLUT_KEY_PAGE_UP:
01285         ztran -= 0.2f;
01286         break;
01287 
01288       case GLUT_KEY_PAGE_DOWN:
01289         ztran += 0.2f;
01290         break;
01291 
01292       default:
01293         printf ("Special key %d pressed. No action there yet.\n", key);
01294         break;
01295       }
01296     }
01297   redraw_needed=1;
01298   glutPostRedisplay();
01299 }
01300 
01301 static int wait_count = 0;
01302 
01303 /* Draw timer */
01304 void RedisplayTimerFunc(int val)
01305 {
01306   if(val == 1)
01307     {
01308       if(0 != emcStatusBuffer && 0 != livePlotList)
01309         {
01310           if(emcStatusBuffer->peek() == EMC_STAT_TYPE)
01311             {
01312               emcStatus = (EMC_STAT *) emcStatusBuffer->get_address();
01313               if(last_pose.tran.x != emcStatus->motion.traj.actualPosition.tran.x ||
01314                  last_pose.tran.y != emcStatus->motion.traj.actualPosition.tran.y ||
01315                  last_pose.tran.z != emcStatus->motion.traj.actualPosition.tran.z ||
01316                   
01317                  last_pose.a != emcStatus->motion.traj.actualPosition.a ||                  
01318                  last_pose.b != emcStatus->motion.traj.actualPosition.b ||                  
01319                  last_pose.c != emcStatus->motion.traj.actualPosition.c  
01320                  )
01321                 {
01322 
01323 
01324                   livePlotList->store_at_tail(&(emcStatus->motion.traj.actualPosition),
01325 
01326                                               sizeof(EmcPose),1);
01327                   timer_count++;
01328                   wait_count = 0;
01329                   if(timer_count%refresh_count == 0)
01330                     {
01331                       RebuildLivePlot();
01332                       redraw_needed=1;
01333                       glutPostRedisplay();
01334                       wait_count = 0;
01335                     }
01336                   last_pose = emcStatus->motion.traj.actualPosition;
01337                 }
01338               else
01339                 {
01340                   wait_count++;
01341                   if(wait_count > 2*refresh_count)
01342                     {
01343                       if(timer_count > 0)
01344                         {
01345                           RebuildLivePlot();
01346                         }
01347                       redraw_needed=1;
01348                       glutPostRedisplay();
01349                       timer_count = 0;
01350                       wait_count = 0;
01351                     }
01352                 }
01353             }
01354           else
01355             {
01356               wait_count++;
01357               if(wait_count > 2*refresh_count)
01358                 {
01359                   if(timer_count > 0)
01360                     {
01361                       RebuildLivePlot();
01362                     }
01363                   redraw_needed=1;
01364                   glutPostRedisplay();
01365                   timer_count = 0;
01366                   wait_count = 0;
01367                 }
01368             }
01369           glutTimerFunc(50,&RedisplayTimerFunc,1);
01370         }
01371     }
01372 }
01373 
01374 
01375 
01376 static int iniLoad(const char *filename)
01377 {
01378   INIFILE inifile;
01379   const char *inistring;
01380   char version[INIFILE_MAX_LINELEN];
01381   int saveInt;
01382   double saveDouble;
01383 
01384   // open it
01385   if (-1 == inifile.open(filename)) {
01386     return -1;
01387   }
01388 
01389   if (NULL != (inistring = inifile.find("DEBUG", "EMC"))) {
01390     // copy to global
01391     if (1 != sscanf(inistring, "%i", &EMC_DEBUG)) {
01392       EMC_DEBUG = 0;
01393     }
01394   }
01395   else {
01396     // not found, use default
01397     EMC_DEBUG = 0;
01398   }
01399 
01400   if (EMC_DEBUG & EMC_DEBUG_VERSIONS) {
01401     if (NULL != (inistring = inifile.find("VERSION", "EMC"))) {
01402       // print version
01403       sscanf(inistring, "$Revision: %s", version);
01404       rcs_print("Version:  %s\n", version);
01405     }
01406     else {
01407       // not found, not fatal
01408       rcs_print("Version:  (not found)\n");
01409     }
01410 
01411     if (NULL != (inistring = inifile.find("MACHINE", "EMC"))) {
01412       // print machine
01413       rcs_print("Machine:  %s\n", inistring);
01414     }
01415     else {
01416       // not found, not fatal
01417       rcs_print("Machine:  (not found)\n");
01418     }
01419   }
01420 
01421   if (NULL != (inistring = inifile.find("NML_FILE", "EMC"))) {
01422     // copy to global
01423     strcpy(EMC_NMLFILE, inistring);
01424   }
01425   else {
01426     // not found, use default
01427   }
01428 
01429 
01430   // close it
01431   inifile.close();
01432 
01433   return 0;
01434 }
01435 
01436 
01437 
01438 
01439 int main(int argc, char **argv)
01440 {
01441 
01442 
01443   // process command line args
01444   emcGetArgs(argc, argv);
01445 
01446   // initialize globals
01447   emcInitGlobals();
01448 
01449   // get configuration information
01450   iniLoad(EMC_INIFILE);
01451   
01452   // load rs274ngc parameters.
01453   rs274ngc_ini_load(EMC_INIFILE);
01454 
01455   emcStatusBuffer
01456     = new RCS_STAT_CHANNEL(emcFormat, "emcStatus", "xemc", EMC_NMLFILE);
01457   if (! emcStatusBuffer->valid())
01458     {
01459       printf("emcStatusBuffer NOT valid.\n");
01460       printf("\n -- \tYou can ignore any errors above this line \n"
01461              "\t if all you want to do is view a tool path from \n"
01462              "\t an rs274ngc program, but plotting\n"
01463              "\t live EMC movement will not be possible.\n\n");
01464       emcStatus = new EMC_STAT();
01465       emcStatus->motion.traj.position.tran.x = 0.0;
01466       emcStatus->motion.traj.position.tran.y = 0.0;
01467       emcStatus->motion.traj.position.tran.z = 0.0;
01468       emcStatus->motion.traj.position.a = 0.0;
01469       emcStatus->motion.traj.position.b = 0.0;
01470       emcStatus->motion.traj.position.c = 0.0;
01471       emcStatus->motion.traj.queue =0;
01472       emcStatus->motion.traj.velocity=1.0;
01473       emcStatus->motion.traj.maxVelocity=1.0;
01474       emcStatus->motion.traj.linearUnits=0.03937007874016;
01475       emcStatus->motion.traj.angularUnits=1.0;
01476       emcStatus->io.tool.toolInSpindle=0;
01477       emcStatus->io.coolant.flood=0;
01478       emcStatus->io.tool.toolPrepped=0;
01479     }
01480   else
01481     {
01482       if(emcStatusBuffer->peek() == EMC_STAT_TYPE)
01483         {
01484           emcStatus = (EMC_STAT *) emcStatusBuffer->get_address();
01485         }
01486       livePlotList  = new RCS_LINKED_LIST();
01487     }
01488   emcCommandBuffer
01489     = new RCS_CMD_CHANNEL(emcFormat, "emcCommand", "xemc", EMC_NMLFILE);
01490 
01491   printf("\n********************************************************\n\n");
01492   printf("EMC 3-D Plotter\n");
01493   printf("\nKeyboard Controls:\n");
01494   printf("\tTranslate X:  \t<LEFT ARROW KEY>/<RIGHT ARROW KEY>\n");
01495   printf("\tTranslate Y:  \t<UP ARROW KEY>/<DOWN ARROW KEY>\n");
01496   printf("\tTranslate Z:  \t<PAGE UP KEY>/<PAGE DOWN KEY>\n");
01497   printf("\n");
01498   printf("\tRotate around X axis:  \t<SHIFT><LEFT ARROW KEY>/<SHIFT><RIGHT ARROW KEY>\n");
01499   printf("\tRotate around Y axis: \t<SHIFT><UP ARROW KEY>/<SHIFT><DOWN ARROW KEY>\n");
01500   printf("\tRotate around Z axis: \t<SHIFT><PAGE UP KEY>/<SHIFT><PAGE DOWN KEY>\n");
01501   printf("\n");
01502   printf("\tView from X perspective:          \tx\n");
01503   printf("\tView from Y perspective:          \ty\n");
01504   printf("\tView from Z perspective:          \tz\n");
01505   printf("\tView from 45 degree angle:        \tk\n");
01506   printf("\tReset view:                       \t<SPACE KEY>\n");
01507   printf("\tClear live plot(Blue):            \tc\n");
01508   printf("\tToggle display of programmed plot(White)     \tp\n");
01509   printf("\tToggle display of rotation frames            \tr\n");
01510   printf("\tToggle display of live plot(Blue)            \tl\n");
01511   printf("\tQuit:                             \t<ESC KEY>\n");
01512   printf("\n********************************************************\n\n");
01513 
01514     /* Initialize GLUT state - glut will take any command line arguments that pertain to it or
01515        X Windows - look at its documentation at http://reality.sgi.com/mjk/spec3/spec3.html */
01516     glutInit(&argc, argv);
01517 
01518     /* Select type of Display mode:
01519      Double buffer
01520      RGBA color
01521      Alpha components supported
01522      Depth buffer */
01523     glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
01524 
01525     for(int i = 0; i < argc; i++)
01526       {
01527         if((!strcmp(argv[i],"-prog") || !strcmp(argv[i],"--prog"))
01528            && i < argc -1)
01529           {
01530             Filename = argv[++i];
01531           }
01532         if(!strcmp(argv[i],"-f")
01533            && i < argc -1)
01534           {
01535             Filename = argv[++i];
01536           }
01537         if((!strcmp(argv[i],"-r") || !strcmp(argv[i],"--refresh"))
01538            && i < argc -1)
01539           {
01540             refresh_count = strtol(argv[++i],0,0);
01541           }
01542         if((!strcmp(argv[i],"-s") || !strcmp(argv[i],"--scale"))
01543            && i < argc -1)
01544           {
01545             scale = strtod(argv[++i],0);
01546           }
01547         if(!strcmp(argv[i],"-t") || !strcmp(argv[i],"--timer")
01548            && i < argc -1)
01549           {
01550             timer_period = strtol(argv[++i],0,0);
01551           }
01552         if(!strcmp("--stewart",argv[i]))
01553           {
01554             show_stewart_platform = 1;
01555             if(argc > i+1)
01556               {
01557                 printf("Showing stewart platform %s\n",argv[i+1]);
01558                 ReadStewartSpecs(argv[++i]);
01559               }
01560             else
01561               {
01562                 ReadStewartSpecs(NULL);
01563               }
01564           }
01565       }
01566 
01567     /* get a 640 x 480 window */
01568     glutInitWindowSize(640, 480);
01569 
01570     /* the window starts at the upper left corner of the screen */
01571     glutInitWindowPosition(0, 0);
01572 
01573     /* Open a window */
01574     window = glutCreateWindow("EMC 3-D Plotter");
01575 
01576     /* Register the function to do all our OpenGL drawing. */
01577     glutDisplayFunc(&DrawGLScene);
01578 
01579     /* Go fullscreen.  This is as soon as possible. */
01580     glutFullScreen();
01581 
01582     /* Even if there are no events, redraw our gl scene. */
01583     //glutIdleFunc(&DrawGLScene);
01584 
01585     /* Register the function called when our window is resized. */
01586     glutReshapeFunc(&ReSizeGLScene);
01587 
01588     /* Register the function called when the keyboard is pressed. */
01589     glutKeyboardFunc(&keyPressed);
01590 
01591     /* Register the function called when special keys (arrows, page down, etc) are pressed. */
01592     glutSpecialFunc(&specialKeyPressed);
01593 
01594     /* Initialize our window. */
01595     InitGL(640, 480);
01596 
01597     /* Start timer function to check EMC status every 50 milliseconds.*/
01598     if(0 != emcStatusBuffer)
01599       {
01600         glutTimerFunc(timer_period,&RedisplayTimerFunc,1);
01601       }
01602 
01603     /* Start Event Processing Engine */
01604     glutMainLoop();
01605 
01606     if(0 != emcStatusBuffer)
01607       {
01608         delete emcStatusBuffer;
01609         emcStatusBuffer=0;
01610       }
01611     if(0 != emcCommandBuffer)
01612       {
01613         delete emcCommandBuffer;
01614         emcCommandBuffer=0;
01615       }
01616     return 1;
01617 }
01618 
01619 
01620 
01621 
01622 
01623 
01624 
01625 
01626 

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