Data Glove Interaction

Part 4 – Data Glove Interaction
In this session, you are going to learn on how to setup the data glove and use it for
interaction in OpenGL Performer. The 5DT Data Glove Ultra is a hand data motion
capturing solution for animation and virtual reality. This glove measures finger flexure as
well as the abduction between the fingers. Finger flexure is measured at two places (1st
joint (knuckle), 2nd joint) on each finger.
Connecting the glove
Connect the glove to the PC as shown in the Figure above. You can use GloveManager
(Start-> All Programs-> 5DT-> Data Glove Ultra-> Glove Manager) to test the
operation of the glove. The details of the operation can be found in Section 4 of the 5DT
Data Glove Ultra Manual, also available from the Start menu.
Setting up the glove
1. After the data glove is connected, it is time to set it up for interaction in our
program. First of all, the necessary header files need to be included.
#include <stdio.h>
#include <string.h>
#include <windows.h> // for Sleep
// --The data glove header file
#include "fglove.h"
2. The variables are declared.
// Variable declarations
fdGlove *glove = NULL;
char
*szPort
= "USB";
char szPortToOpen[6];
int glovetype = FD_GLOVENONE;
//the dataglove
//type of port
//string to store the port to open
//glove type
3. Next, the USB ports available on the computer are scanned to detect the available
gloves. The number of gloves found during the scan will be returned as an
integer value. The first parameter of
int fdScanUSB(unsigned short *aPID, int *nNumMax)
is a pointer to an unsigned short array of length nNumMax. The USB Product IDs
of the gloves found are returned in this array of which the following PIDs are
defined:
DG14U_R – Data Glove 14 Ultra Right-hand
DG14U_L – Data Glove 14 Ultra Left-hand
DG5U_R – Data Glove 5 Ultra Right-hand
DG5U_L – Data Glove 5 Ultra Left-hand
// Glove connected to USB port
strcpy(szPortToOpen, szPort);
//Test the USB port of which the glove is connected
if (strcmp(szPort,"USB") == 0)
{
unsigned short aPID[4];
//USB product ID of the gloves
int nNumFound = 4;
//Number of USB port found
int nChosen = 0;
//Glove chosen
// Scan the USB for the available glove
fdScanUSB(aPID,nNumFound);
// Print out the available gloves in the console
for (int c = 0; c < nNumFound; c++)
{
printf("Available USB Gloves:\n");
printf("%i - ",c);
switch (aPID[c])
{
case DG14U_R:
printf("Data Glove 14 Ultra Right\n");
break;
case DG14U_L:
printf("Data Glove 14 Ultra Left\n");
break;
case DG5U_R:
printf("Data Glove 5 Ultra Right\n");
break;
case DG5U_L:
printf("Data Glove 5 Ultra Left\n");
break;
default:
printf("Unknown\n");
}
}
// Getting user input
printf("Please enter option:");
scanf("%i",&nChosen);
sprintf(szPortToOpen,"USB%i",nChosen);
// Initialise the glove device on the specified port
fdOpen(szPortToOpen);
}
When the glove(s) is found, a prompt is displayed for the user to choose the
desired glove to open.
4. Test that the glove open process is carried out successfully. NULL is returned if
an error occurred.
printf("Attempting to open glove on %s ..", szPortToOpen);
// Initialising glove and make sure that it is not NULL
if((glove = fdOpen(szPortToOpen)) == NULL)
{
printf("Failed!");
return -1;
}
else
printf("Succeeded!");
5. Next, check the type of currently connected glove and print the details.
number of sensor is also obtained
The
// Obtains the type of the currently connected glove
char *szType = "?";
glovetype = fdGetGloveType(glove);
switch (glovetype)
{
case FD_GLOVENONE: szType = "None"; break;
case FD_GLOVE7:
szType = "Glove7"; break;
case FD_GLOVE7W:
szType = "Glove7W"; break;
case FD_GLOVE16:
szType = "Glove16"; break;
case FD_GLOVE16W: szType = "Glove16W"; break;
case FD_GLOVE5U: szType = "DG5 Ultra serial"; break;
case FD_GLOVE5UW: szType = "DG5 Ultra serial, wireless"; break;
case FD_GLOVE5U_USB: szType = "DG5 Ultra USB"; break;
case FD_GLOVE14U: szType = "DG14 Ultra serial"; break;
case FD_GLOVE14UW: szType = "DG14 Ultra serial, wireless"; break;
case FD_GLOVE14U_USB: szType = "DG14 Ultra USB"; break;
}
// Print the glove type, indicating whether it is right- or left- handed
printf( "glove type: %s\n", szType );
printf( "glove handedness: %s\n",
fdGetGloveHand(glove)==FD_HAND_RIGHT?"Right":"Left" );
// Obtains the number of available sensors values
int iNumSensors = fdGetNumSensors(glove);
printf( "glove num sensors: %d\n", iNumSensors );
FD_GLOVE7 and FD_GLOVE7W refer to the original 5+2 (tilt angles) sensor glove
(5DT Data Glove 5). The W suffix indicates a wireless model. FD_GLOVE16 and
FD_GLOVE16W refer to the Data Glove 16. FD_GLOVE14, FD_GLOVE14W, and
FD_GLOVE14_USB refer to the Data Glove 14 Ultra. The USB suffix refers to the
Universal Serial Bus interface. In order to accommodate all glove types the
fdGetNumSensors() function currently returns 18 sensors. The additional two
sensors are defined as the original tilt angles that are not present in the 16sensor glove.
Although the 5-sensor glove can measure only average flexure, the driver will
attempt to fill in missing values. The number of sensors returned can therefore
be of higher dimension.
Sensor Positions for the 5DT Data Glove 5
Sensor Mappings for the 5DT Data Glove 5 and 5DT Data Glove 5 Ultra
* Both these driver sensor indices will return the same value when the 5DT Data
Glove 5 or Data Glove Ultra is used
+ Not available on the Data Glove 5 Ultra
6. In the simulation loop, print the glove scaled values. The current gesture is also
obtained and printed.
// Simulation loop
for (int i=0; i<10; i++ )
{
// Value for the current gesture
int gesture;
if (glovetype==FD_GLOVE7 || glovetype==FD_GLOVE7W)
{
// Display the glove scaled values
printf("Gloves scaled values");
printf("Thumb
%.1f ",
fdGetSensorScaled(glove,FD_THUMBNEAR));
printf("Index
%.1f ",
fdGetSensorScaled(glove,FD_INDEXNEAR));
printf("Middle
%.1f ",
fdGetSensorScaled(glove,FD_MIDDLENEAR));
printf("Ring
%.1f ",
fdGetSensorScaled(glove,FD_RINGNEAR));
printf("Little
%.1f \n",
fdGetSensorScaled(glove,FD_LITTLENEAR));
printf( "roll=%.1f,pitch=%.1f\n",
fdGetSensorScaled(glove,FD_ROLL),
fdGetSensorScaled(glove,FD_PITCH));
}
else
{
// Display the glove scaled values
printf("Gloves scaled values");
printf("ThumbNear %.1f,",
fdGetSensorScaled(glove,FD_THUMBNEAR));
printf("ThumbFar %.1f,",
fdGetSensorScaled(glove,FD_THUMBFAR));
printf("ThumbIndex
%.1f ",
fdGetSensorScaled(glove,FD_THUMBINDEX));
printf("IndexNear %.1f,",
fdGetSensorScaled(glove,FD_INDEXNEAR));
printf("IndexFar %.1f,",
fdGetSensorScaled(glove,FD_INDEXFAR));
printf("IndexMiddle
%.1f ",
fdGetSensorScaled(glove,FD_INDEXMIDDLE));
printf("MiddleNear
%.1f,",
fdGetSensorScaled(glove,FD_MIDDLENEAR));
printf("MiddleFar %.1f,",
fdGetSensorScaled(glove,FD_MIDDLEFAR));
printf("MiddleRing
%.1f ",
fdGetSensorScaled(glove,FD_MIDDLERING));
printf("RingNear %.1f,",
fdGetSensorScaled(glove,FD_RINGNEAR));
printf("RingFar
%.1f,",
fdGetSensorScaled(glove,FD_RINGFAR));
printf("RingLittle
%.1f ",
fdGetSensorScaled(glove,FD_RINGLITTLE));
printf("LittleNear
%.1f,",
fdGetSensorScaled(glove,FD_LITTLENEAR));
printf("LittleFar %.1f ",
fdGetSensorScaled(glove,FD_LITTLEFAR));
printf("ThumbPalm %.1f ",
fdGetSensorScaled(glove,FD_THUMBPALM));
printf("WristBend %.1f \n",
fdGetSensorScaled(glove,FD_WRISTBEND));
printf( "roll=%.1f,pitch=%.1f\n",
fdGetSensorScaled(glove,FD_ROLL),
fdGetSensorScaled(glove,FD_PITCH));
}
// Obtain the current gesture being performed
gesture = fdGetGesture(glove);
printf("Gesture %d\n", gesture);
// Wait for a while before the next iteration
Sleep(1000);
}
It is also possible to obtain the glove raw data by using
unsigned short fdGetSensorRaw(fdGlove *pFG, int nSensor)
Gesture Illustration
7. Finally, close the glove device and frees the communication port
printf( "closing glove\n" );
// Frees the glove device and communications port
fdClose(glove);
Data Glove Interaction
Now, it is time to use the data glove as an interaction device in OpenGL Performer. A
particular gesture will cause an operation to be carried out on the 3D model.
1. Add Step 1 to 4 above to the basic model loading program that you have created
earlier.
2. Make the root node which is a type of pfNode to be the child of pfDCS, a branch of
node that represents a dynamic coordinate system. It is used here as we want to
change the transformation of the 3D model during the execution of the
application. Remember to replace the child of pfScene with the dcs node instead
of the pfNode node. The other part of the program remains the same.
// Add the 3D model as a child of pfDCS node
pfDCS *dcs = new pfDCS;
dcs->addChild(root);
scene->addChild(dcs);
3. Put the statements that set the viewpoint of the channel (previously in the
simulation loop) before the simulation loop. Declare as well as initialise the
variables to be used in the simulation loop.
// Set the initial viewpoint
view.hpr.set(45.0f, -10.0f, 0);
view.xyz.set(20.0f, -20.0f, 5.0f);
chan->setView(view.xyz, view.hpr);
// Variable declaration
float rotX=0.0f, scale=1.0f;
4. In the simulation loop, detect the current gesture. Perform some action on the
3D model based on the gesture. Here, gesture 1 will cause the model to rotate
along the X axis, while gesture 3 will enlarge the model. Gesture 15 will cause
the scene to be reset to its original stage.
// Simulation loop
while (t < 40.0f)
{
int gesture;
pfSync();
// Obtain the current gesture being performed
gesture = fdGetGesture(glove);
printf("Gesture %d\n", gesture);
// Perform some action on the object based on the gesture
// performed
if(gesture == 1)
{
// Changing the pitch value - Rotation along X axis
dcs->setRot(0.0f, rotX, 0.0f);
rotX +=0.05f;
}
else if(gesture == 3)
{
// Enlarge the model
dcs->setScale(scale);
scale += 0.01f;
}
else if(gesture == 15)
{
// reset the model
rotX=0.0f;
scale=1.0f;
dcs->setRot(0.0f, rotX, 0.0f);
dcs->setScale(scale);
}
pfFrame();
}
5. Now, you are ready to compile the program and interact with the model using the
data glove!
Extra exercise for those interested
Add more interaction using the different available gesture.
model, rotate it along other axes, etc.
You can translate the 3D
Summary
In this session, you have learned how to setup and use the data glove. For more
information about the data glove SDK, please refer to the 5DT Data Glove Ultra Manual
found at Start-> All Programs-> 5DT-> Data Glove Ultra-> 5DT Data Glove Ultra
Manual