/*******************************************************************/ /* This program will open a connection to the Mattel PowerGlove */ /* via the serial port. It then reads data from the port and */ /* writes to standard output. */ /* Written for the Personal Iris by Greg Newby, Bob Zeh, and */ /* Bill Tarolli. */ /* This program is supplied "as is." No warranty is implied. */ /* For additional information, contact Greg Newby /* gbnewby@alexia.lis.uiuc.edu). */ /* 7/10/91. All Rights Etc. */ /*******************************************************************/ /* x, y, and z go from -127 to 128 twist goes from 0 to 11 fingers = 0 to 3 */ /* Note: some #include files have different names on other machines*/ #include /* IRIS graphics library */ #include /* keyboard, mouse, etc. */ #include #include #include #include #include "sys/callo.h" #include #include #define threshhold 3.0 /*1.5*/ #define THEN /*then*/ #define ELSE else #define OR || #define AND && #define FLOAT (float) #define TRUNC (int) #define inertia 0.7 #define sensitivity 0.25 #define PORT_ID "/dev/ttyd1" /* Your port must be configured correctly for it to work. Must be */ /* read/writable and have correct settings for gettty */ typedef struct { /* where the data go */ int x, y, z, thumb, one, two, three, rot; } pglove_data; int file_id; float xg, yg, zg, xg_delta, yg_delta, zg_delta, old_x, old_y, old_z, old_x_delta, old_y_delta, old_z_delta; initialize_graphics() { float view_distance, near_clipping_plane, far_clipping_plane, aspect_ratio; int field_of_view; keepaspect(1,1); prefposition(10, 900, 10, 900); winopen("Glove Stuff"); view_distance = 100.0; field_of_view = 600; near_clipping_plane = 0.1; far_clipping_plane = 1000.1; aspect_ratio = 1.0; perspective(field_of_view, aspect_ratio, near_clipping_plane, far_clipping_plane); polarview(view_distance, 0, 0, 0); } tell_user_stuff() { printf("plug in the AGE box. Plug in Convertor box.\n"); printf("Make sure red light is on on the convertor box. \n"); printf("glove will beep. listen to glove- clicking and whirring. point glove.\n"); printf("towards screen - sensory array. red lights should be blinking.\n"); printf("Put on glove. \n"); printf("Hold the glove at a comfortable distance from the screen\n"); printf("and press the 'Center' button on the glove to establish the center of the glove's movements.\n"); printf("Click LEFT mouse button to continue. \n"); while (getbutton(LEFTMOUSE)==0); /*wait til mouse button clicked */ } /*******************************************************************/ /* Routine to initialize the serial port */ /*******************************************************************/ int init_pglove() /* returns the file_id for the open file */ { extern char *sys_errlist[]; int rslt; struct termios tbuf; file_id = open(PORT_ID, O_RDWR, 0); if (file_id == -1) { printf("Error on open call\n"); perror(*sys_errlist); return(1); } tbuf.c_iflag = 0; tbuf.c_oflag = 0; tbuf.c_lflag = 0; tbuf.c_cflag = B9600 | CS8 | CLOCAL | CREAD; rslt = ioctl(file_id, TCSETA, &tbuf); if (rslt == -1) { fprintf(stderr, "ioctl failed\n"); perror(*sys_errlist); return(1); } ioctl(file_id, TCFLSH,2); /* flush the port */ return(file_id); } /*******************************************************************/ /* Puts current glove data in the structure */ /*******************************************************************/ int read_pglove(file_id, pglove) pglove_data *pglove; int file_id; { int ret, temp; char buf[BUFSIZ]; char command[BUFSIZ]; command[0] = 2; write(file_id,command,1); ret = read(file_id,buf,14); /* Check header bytes to see if the data are good */ if (!((ret > 3) && (buf[0] == (0x81 - 127)) && (buf[1] == (0xDE - 127)) && (buf[2] == (0xDE - 127)))) return(1); /* Assign X, Y, and Z (need to query 1st bit for sign on Iris) */ pglove->x = buf[3]; if (buf[3] > 127) pglove->x -= 256; pglove->y = buf[4]; if (buf[4] > 127) pglove->y -= 256; pglove->z = buf[5]; if (buf[5] > 127) pglove->z -= 256; /* Assign rotation and (bit-shifted) rotation values */ pglove->rot = buf[6]; temp = buf[7]; pglove->three = temp & 3; temp = temp >> 2; pglove->two = temp & 3; temp = temp >> 2; pglove->one = temp & 3; temp = temp >> 2; pglove->thumb = temp & 3; return(0); } /*******************************************************************/ /* A small test program to write the data to stdandard output */ /* An optional argument determines time between samples */ /*******************************************************************/ main(argc, argv) int argc; char *argv[]; { pglove_data pglove; int sleepval = 10; /* number of ticks @ 100/sec between samples */ /* on the Iris, 7 is the min for reliability */ int file_id; /* use given argument for delay time, else use default (above) */ if (argc > 1) sleepval = atoi(argv[1]); tell_user_stuff(); initialize_graphics(); color(BLACK); clear(); file_id = init_pglove(); /* open the serial port */ read_pglove(file_id, &pglove); xg = pglove.x; yg = pglove.y; zg = pglove.z; old_x = xg; old_y = yg; old_z = zg; xg_delta = 0.0; yg_delta = 0.0; zg_delta = 0.0; old_x_delta = xg_delta; old_y_delta = yg_delta; old_z_delta = zg_delta; while (getbutton(QKEY) ==0) { old_x = pglove.x; old_y = pglove.y; old_z = pglove.z; old_x_delta = xg_delta; old_y_delta = yg_delta; old_z_delta = zg_delta; read_pglove(file_id, &pglove); color(WHITE); xg_delta = (xg_delta * inertia) + ((pglove.x-old_x) * sensitivity); yg_delta = (yg_delta * inertia) + ((pglove.y-old_y) * sensitivity); zg_delta = (zg_delta * inertia) + ((pglove.z-old_z) * sensitivity); /* buggy always beeps if ((xg_delta > old_x_delta * threshhold) OR (yg_delta > old_y_delta * threshhold) OR (zg_delta > old_z_delta * threshhold)) { setbell(1); ringbell(); } */ if( ( (xg_delta > 0.0) && (xg_delta > (old_x_delta * threshhold))) || ( (xg_delta < 0.0) && (xg_delta < (old_x_delta * threshhold))) || ( (yg_delta > 0.0) && (yg_delta > (old_y_delta * threshhold))) || ( (yg_delta < 0.0) && (yg_delta < (old_y_delta * threshhold))) || ( (zg_delta > 0.0) && (zg_delta > (old_z_delta * threshhold))) || ( (zg_delta < 0.0) && (zg_delta < (old_z_delta * threshhold))) ) bad(); xg = xg + xg_delta; yg = yg + yg_delta; zg = zg + zg_delta; draw(xg, yg, zg); printf("pglove.x=%i .y=%i .z=%i xg_delta=%4.4f yg_d=%4.4f zg_d=%4.4f\n", pglove.x, pglove.y, pglove.z, xg_delta, yg_delta, zg_delta); sginap(sleepval); /* sleep until next query */ } } /**** end of main ****/ /**** we got bad data *****/ bad() { setbell(1); ringbell(); printf(" Bad! "); }