5DT Data Glove plugin 1.0

D:/SVN/Scol/trunk/plugins/glove5DT/src/GloveObject.cpp

00001 //###################################################################################
00002 //#                                                                     Glove Object                                                                                    #
00003 //#                                                             Used To Handle a 5DT Glove                                                                    #
00004 //#                                                                       Author :                                                                            #
00005 //#                                                                   Aymeric SUTEAU                                                                                    #
00006 //#                                                                    LISA - ANGERS                                                                                    #
00007 //###################################################################################
00008 
00009 
00010 /* HEADER INCLUDE */
00011 #include "Glove.h"
00012 #include <string.h>
00013 
00014 
00015 /* GLOBAL VARIABLES */
00016 // Thresholds for calibration procedure
00017 float f_thresholdUpperCoeff = 0.3f, f_thresholdLowerCoeff = 0.3f;
00018 
00019 
00020 /*------------------------------- CALLBACK FUNCTION -------------------------------*/
00021 void GloveCallback(LPVOID param) 
00022 {
00023         // Cast void pointer to GloveObject type before using
00024         GloveObject *pGloveObject = (GloveObject*) param;
00025         // If we retrieve a valid pointer, we call the function which will update the sensors values
00026         if (pGloveObject)
00027                 pGloveObject->UpdateGlove();
00028 }
00029 
00030 
00031 /*-------------------------- CONSTRUCTOR AND DESTRUCTOR ---------------------------*/
00032 GloveObject::GloveObject() : Thread() 
00033 {
00034         SetGlove(NULL);
00035         SetPort(NULL);
00036         SetShowRaw(false);
00037         SetGloveType(FD_GLOVENONE);
00038         SetType("?");
00039         SetNbrOfSensors(-1);
00040         SetGestureIndex(-1);
00041   SetCalibrationDone(true);
00042   SetInitValuesDone(true);
00043   SetInitDone(false);
00044   SetUSBIndex(0);
00045   SetGestureMode(GESTURE_WITH_THUMB);
00046 
00047   // Thread handling
00048   this->start();
00049   this->isRunning = true;
00050 }
00051 
00052 GloveObject::~GloveObject() 
00053 {
00054   // Destroy dynamic table containing data glove serial number 
00055   //delete [] szSerialNumber;  
00056 
00057   // Thread handling
00058   this->isRunning = false;
00059   this->stop();
00060 }
00061 
00062 
00063 /*------------------------------ GETTERS AND SETTERS ------------------------------*/
00064 fdGlove * GloveObject::GetGlove() 
00065 {
00066         return this->pGlove;
00067 }
00068 
00069 void GloveObject::SetGlove(fdGlove * glove)
00070 {
00071         this->pGlove = glove;
00072 }
00073 
00074 char * GloveObject::GetPort() 
00075 {
00076         return this->szPort;
00077 }
00078 
00079 void GloveObject::SetPort(char * port) 
00080 {
00081         this->szPort = port;
00082 }
00083 
00084 bool GloveObject::IsShowRaw() 
00085 {
00086         return this->bShowRaw;
00087 }
00088 
00089 void GloveObject::SetShowRaw(bool showRaw) 
00090 {
00091         this->bShowRaw = showRaw;
00092 }
00093 
00094 int GloveObject::GetGloveType() 
00095 {
00096         return this->iGloveType;
00097 }
00098 
00099 void GloveObject::SetGloveType(int gloveType) 
00100 {
00101         this->iGloveType = gloveType;
00102 }
00103 
00104 char * GloveObject::GetType() 
00105 {
00106         return this->szType;
00107 }
00108 
00109 void GloveObject::SetType(char * type) 
00110 {
00111         this->szType = type;
00112 }
00113 
00114 int GloveObject::GetGloveHand() 
00115 {
00116         return this->iGloveHand;
00117 }
00118 
00119 void GloveObject::SetGloveHand(int gloveHand) 
00120 {
00121         this->iGloveHand = gloveHand;
00122 }
00123 
00124 char * GloveObject::GetHand() 
00125 {
00126         return this->szHand;
00127 }
00128 
00129 void GloveObject::SetHand(char * hand) 
00130 {
00131         this->szHand = hand;
00132 }
00133 
00134 int GloveObject::GetNbrOfSensors() 
00135 {
00136         return this->iNbrOfSensors;
00137 }
00138 
00139 void GloveObject::SetNbrOfSensors(int nbSensors) 
00140 {
00141         this->iNbrOfSensors = nbSensors;
00142 }
00143 
00144 std::string GloveObject::GetSerialNumber() 
00145 {
00146   return this->szSerialNumber;
00147 }
00148 
00149 void GloveObject::SetSerialNumber(std::string serialNumber) 
00150 {
00151   this->szSerialNumber = serialNumber;
00152 }
00153 
00154 bool GloveObject::GetCalibrationDone()
00155 {
00156   return this->bCalibrationDone;
00157 }
00158 
00159 void GloveObject::SetCalibrationDone(bool status) 
00160 {
00161   this->bCalibrationDone = status;
00162 }
00163 
00164 bool GloveObject::GetInitValuesDone() 
00165 {
00166   return this->bInitValuesDone;
00167 }
00168 
00169 void GloveObject::SetInitValuesDone(bool status) 
00170 {
00171   this->bInitValuesDone = status;
00172 }
00173 
00174 bool GloveObject::GetInitDone() 
00175 {
00176   return this->bInitDone;
00177 }
00178 
00179 void GloveObject::SetInitDone(bool status) 
00180 {
00181   this->bInitDone = status;
00182 }
00183 
00184 int GloveObject::GetUSBIndex() 
00185 {
00186   return this->iUSBIndex;
00187 }
00188 
00189 void GloveObject::SetUSBIndex(int index) 
00190 {
00191   this->iUSBIndex = index;
00192 }
00193 
00194 int GloveObject::GetGestureMode() 
00195 {
00196   return this->iGestureMode;
00197 }
00198 
00199 void GloveObject::SetGestureMode(int gestureMode) 
00200 {
00201   this->iGestureMode = gestureMode; 
00202 }
00203 
00204 
00205 /*----- Return gesture index between 0 and 15 (thumb not handled) -----*/
00206 int GloveObject::GetGestureIndex() 
00207 {
00208         return this->iGestureIndex;
00209 }
00210 
00211 void GloveObject::SetGestureIndex(int gestureIndex) 
00212 {
00213         this->iGestureIndex = gestureIndex;
00214 }
00215 
00216 
00217 /*----- Return new gesture index between 0 and 31 (thumb handled) -----*/
00218 int GloveObject::GetGestureWithThumbIndex() 
00219 {
00220   int *pIndexValues, gestureValue = 0, thresholdDiff = 0;
00221   pIndexValues = new int[GetNbrOfSensors()];
00222 
00223   // Retrieve the current sensors values and the thresholds defined during auto calibration
00224   fdGetSensorRawAll(GetGlove(), pValues);
00225   fdGetCalibrationAll(GetGlove(), pMax, pMin);
00226   
00227   // Define a new index position (boolean) for each finger
00228   for (int i=0; i<GetNbrOfSensors(); i++) 
00229   {
00230           // Define new thresholds
00231     thresholdDiff = pMax[i] - pMin[i];
00232     pMax[i] -= (int)(f_thresholdUpperCoeff*thresholdDiff);
00233     pMin[i] += (int)(f_thresholdLowerCoeff*thresholdDiff);
00234         
00235           // Adjust thresholds with a coefficient
00236     // Normal position : -1
00237     if (pValues[i] >= pMin[i] && pValues[i] <= pMax[i]) 
00238     {
00239       pIndexValues[i] = -1;
00240     }
00241         
00242     // Closed finger : 0
00243     else if (pValues[i] < pMin[i]) 
00244     {
00245       pIndexValues[i] = 0;
00246     }
00247         
00248     // Opened finger : 1
00249     else if (pValues[i] > pMax[i]) 
00250     {
00251       pIndexValues[i] = 1;
00252     }
00253   }
00254   
00255   // Define new gesture index (-1 if normal gesture, otherwise between 0 and 31)
00256   if (pIndexValues[FD_THUMBNEAR] == -1 || pIndexValues[FD_INDEXNEAR] == -1 || pIndexValues[FD_MIDDLENEAR] == -1 || pIndexValues[FD_RINGNEAR] == -1  
00257                                        || pIndexValues[FD_LITTLENEAR] == -1) 
00258   {
00259     // Unrecognizable gesture
00260     gestureValue = -1;
00261   }
00262   
00263   // Otherwise, combine the index values of each finger
00264   else 
00265   {
00266     // Index between 0 and 31 (32 gestures are possible)
00267     gestureValue = pIndexValues[FD_THUMBNEAR] + 2*pIndexValues[FD_INDEXNEAR] + 4*pIndexValues[FD_MIDDLENEAR] + 8*pIndexValues[FD_RINGNEAR]
00268                                               + 16*pIndexValues[FD_LITTLENEAR];
00269   }
00270   return gestureValue;
00271 }
00272 
00273 void GloveObject::SetGestureWithThumbIndex(int gestureWithThumbIndex) 
00274 {
00275         this->iGestureTHIndex = gestureWithThumbIndex;
00276 }
00277 
00278 
00279 /*-------------------------------- ADDITIONAL FUNCTIONS ---------------------------------*/
00280 /*----- Initialize glove object -----*/
00281 bool GloveObject::Init(int gestureMode) 
00282 {
00283   // Check for any available USB glove
00284         unsigned short aPID[5];
00285         int nNumFound = 5, nChosen = 0;
00286   char portName[10] = "USB";
00287   bool bInitOk = false;
00288   //szSerialNumber = new char[12];
00289 
00290   // Scan USB ports
00291   fdScanUSB(aPID, nNumFound);
00292   // DEBUG : MMechostr(MSKDEBUG, "-> Init ...gloves found : %d\n", nNumFound);
00293   for (int i=0; i<nNumFound; i++)
00294   {
00295     // Update the name of current USB port
00296     sprintf(portName, "USB%d", i);
00297 
00298                 // Try to open the first device of the list, else try to open the next one
00299     SetGlove(fdOpen(portName, true));
00300     if (!GetGlove()) 
00301     {
00302       // Initialization failed : data glove already opened
00303       MMechostr(MSKDEBUG, "-> Init ...failed : data glove n.%d already opened\n", i);
00304     }
00305     else 
00306     {
00307       // Set USB port and index
00308       SetPort(portName);
00309       SetUSBIndex(i);
00310       MMechostr(MSKDEBUG, "-> Init ...successful\n");
00311       bInitOk = true;
00312       break;
00313     }
00314         }
00315 
00316   // If no gloves have been found, we must exit the function
00317   if (!bInitOk) 
00318   {
00319     MMechostr(MSKDEBUG, "-> Init ...failed : couldn't open any data glove\n");
00320     return false;
00321   }
00322 
00323   // Retrieve the data glove serial number
00324   char tmpserial[13];
00325   fdGetSerialNumber(GetGlove(), tmpserial);
00326   MMechostr(MSKDEBUG, "Glove 5DT serial : %s", tmpserial);
00327   szSerialNumber = tmpserial;
00328   SetSerialNumber(szSerialNumber);
00329 
00330   // Disable auto calibration (enabled by default)
00331   fdSetAutoCalibrate(GetGlove(), false);
00332 
00333   // Initialize data glove gesture mode
00334   SetGestureMode(gestureMode);
00335 
00336   // Set Glove Type and Hand Type
00337         SetGloveType(fdGetGloveType(pGlove));
00338         switch (GetGloveType()) 
00339   {
00340                 // Not a Glove : we consider that the initialization of the device was a failure
00341                 case FD_GLOVENONE: 
00342                         SetType("None");
00343                         return false; 
00344                         break;
00345 
00346                 // Get Glove Type
00347                 case FD_GLOVE7:    
00348                         SetType("5DT Glove"); 
00349                         break;
00350 
00351                 case FD_GLOVE7W:   
00352                         SetType("5DT Wireless Glove"); 
00353                         break;
00354 
00355                 case FD_GLOVE16:   
00356                         SetType("16DT Glove");
00357                         break;
00358 
00359                 case FD_GLOVE16W:  
00360                         SetType("16DT Wireless Glove"); 
00361                         break;          
00362 
00363                 case FD_GLOVE5U: 
00364                         SetType("DG5 Ultra Series"); 
00365                         break;
00366 
00367                 case FD_GLOVE5UW: 
00368                         SetType("DG5 Wireless Ultra Series"); 
00369                         break;
00370 
00371                 case FD_GLOVE5U_USB: 
00372                         SetType("DG5 Ultra USB");
00373                         break;
00374 
00375                 case FD_GLOVE14U: 
00376                         SetType("DG14 Ultra Series"); 
00377                         break;
00378 
00379                 case FD_GLOVE14UW: 
00380                         SetType("DG14 Wireless Ultra Series"); 
00381                         break;
00382 
00383                 case FD_GLOVE14U_USB: 
00384                         SetType("DG14 Ultra USB"); 
00385                         break;          
00386         }
00387         SetGloveHand(fdGetGloveHand(pGlove));
00388         if (GetGloveHand() == FD_HAND_RIGHT)
00389                 SetHand("Right");
00390         else
00391                 SetHand("Left");
00392 
00393         // Set Number of Glove Sensors
00394         SetNbrOfSensors(fdGetNumSensors(pGlove));
00395 
00396         // Init successful
00397   SetInitDone(true);
00398         return true;
00399 }
00400 
00401 
00402 /*----- Initialize data glove sensors values -----*/
00403 void GloveObject::InitValues() 
00404 {
00405         // Get Number of Values to Retrieve
00406         pValues = new unsigned short[GetNbrOfSensors()];
00407         pMax = new unsigned short[GetNbrOfSensors()];
00408         pMin = new unsigned short[GetNbrOfSensors()];
00409 
00410         // Define Minimum and Maximum Values Before Calibration
00411         for (int i=0; i<GetNbrOfSensors(); i++) 
00412   {
00413                 pMin[i] = 0;
00414                 pMax[i] = 4095;
00415         }
00416 
00417   // Update initialization procedure status
00418   SetInitValuesDone(true);
00419 }
00420 
00421 
00422 /*----- Set callback to be called when a new packet is received by the driver -----*/
00423 void GloveObject::SetCallback() 
00424 {
00425         // Set the update function callback (once the calibration is done)
00426         fdSetCallback(GetGlove(), (void*)GloveCallback, this);
00427 }
00428 
00429 
00430 /*----- Delete callback -----*/
00431 void GloveObject::DeleteCallback() 
00432 {
00433         // Delete the callback function previously added (in order to stop the acquisition of sensors values)
00434         fdSetCallback(GetGlove(), NULL, NULL);
00435 }
00436 
00437 
00438 /*----- To be called by glove callback function -----*/
00439 void GloveObject::UpdateGlove() 
00440 {
00441         double angleX = 0.0, angleY = 0.0;
00442         // If and only if a valid pointer to the glove device is available
00443         if (GetGlove()) 
00444   {
00445                 fdGetSensorRawAll(GetGlove(), pValues);                     // Update sensors values
00446 
00447     // Retrieve the current gesture according to the gesture mode
00448     if (GetGestureMode() == 0) 
00449     {
00450                   SetGestureIndex(fdGetGesture(GetGlove()));              // Retrieve and set current gesture index
00451                   PostMessage(HScol, GLOVE_NEWDATA_WITHOUT_THUMB_CB, (int)this, (LPARAM)NULL);
00452     }
00453     else 
00454     {
00455       SetGestureWithThumbIndex(fdGetGesture(GetGlove()));   // Retrieve and set current gesture index (with thumb)
00456       PostMessage(HScol, GLOVE_NEWDATA_CB, (int)this, (LPARAM)NULL);
00457     }
00458 
00459                 // Notify Scol window that a new hand gesture has been made
00460                 PostMessage(HScol, GLOVE_HAND_CB, (int)this, (LPARAM)NULL);
00461         }
00462 }
00463 
00464 
00465 /*----- Close glove -----*/
00466 int GloveObject::Close() 
00467 {
00468         int iErrorCode = fdClose(GetGlove());   // Free the glove device and communication port
00469   SetGlove(NULL);                         // Make sure the pointer is reset
00470   return iErrorCode;
00471 }
00472 
00473 
00474 /*----- Calibrate automatically or manually the glove -----*/
00475 void GloveObject::AutoCalibrate(bool bAuto) 
00476 {
00477   time_t startTime, currentTime;
00478 
00479   // Notify Scol window that the calibration has started
00480   PostMessage(HScol, GLOVE_CALIBRATION_START_CB, (int)this, (LPARAM)NULL);
00481 
00482         // ---------- Case 1 : Auto Calibration
00483   if (bAuto) 
00484   {
00485     MMechostr(MSKDEBUG, "-> AutoCalibrate ...calibration mode : AUTO\n");
00486     // Reset calibration values
00487           for (int i=0; i<18; i++) 
00488     {
00489       pMax[i] = 0;
00490                         pMin[i] = 4095;
00491           }
00492     fdSetCalibrationAll(GetGlove(), pMax, pMin);
00493 
00494     // Enable auto calibration
00495     fdSetAutoCalibrate(GetGlove(), TRUE);
00496 
00497           // Start calibration : the process will last 5 seconds
00498     // During this period, the user must open/close his hand several times to complete calibration process
00499           time(&startTime);
00500           do 
00501     {
00502                   time(&currentTime);
00503           } while ((currentTime - startTime) < 5);
00504 
00505     // Disable auto calibration
00506     fdSetAutoCalibrate(GetGlove(), FALSE);
00507   }
00508 
00509         // ---------- Case 2 : Manual Calibration
00510         else 
00511   {
00512     MMechostr(MSKDEBUG, "-> AutoCalibrate ...calibration mode : MANUAL\n");
00513                 // Default Values to Start Calibration
00514                 for (int i=0; i<GetNbrOfSensors(); i++) 
00515     {
00516                         pMax[i] = 0;
00517                         pMin[i] = 4095;
00518                 }
00519 
00520                 // Get Calibration Start Time
00521                 time(&startTime);
00522                 do 
00523     {
00524                         // Get Sensors Values
00525                         fdGetSensorRawAll(GetGlove(), pValues);
00526 
00527                         // For each value, we get the minimum and maximum
00528                         for (int i=0; i<GetNbrOfSensors(); i++)
00529       {
00530                                 if(pValues[i]!=0) {
00531                                         if (pValues[i] > pMax[i])
00532                                                 pMax[i] = pValues[i];
00533                                         
00534                                         if (pValues[i] < pMin[i]) 
00535                                                 pMin[i] = pValues[i];
00536                                 }
00537                         }
00538 
00539                         // Get Current Time
00540                         time(&currentTime);
00541 
00542                 } while ((currentTime - startTime) < 5);
00543         }
00544 
00545   // Notify Scol window that the calibration has ended
00546   PostMessage(HScol, GLOVE_CALIBRATION_END_CB, (int)this, (LPARAM)NULL);
00547 
00548   // Update calibration status
00549   MMechostr(MSKDEBUG, "-> AutoCalibrate ...calibration done for %s.\n", GetType());
00550   SetCalibrationDone(true);
00551 }
00552 
00553 
00554 /*----- Thread handling -----*/
00555 void GloveObject::run() 
00556 {
00557   try 
00558   {
00559     while(isRunning) 
00560     {
00561       // TODO : Handle USB disconnection of the data glove
00562       // Will be implemented by 5DT Technical support in a few days
00563 
00564       // Calibration
00565       if (!GetCalibrationDone()) 
00566       {
00567         AutoCalibrate(true);            
00568       }
00569 
00570       // Initialize data glove sensors values
00571       else if (!GetInitValuesDone()) 
00572       {
00573         InitValues();
00574       }
00575     }
00576     // Release connection to the data glove
00577     if (Close() == 0) 
00578     {
00579       SetGlove(NULL);
00580     }
00581   }
00582   catch (ThreadException ex) 
00583   {
00584     MMechostr(MSKDEBUG, "error thread : %s\n", ex.getMessage().c_str());
00585   }             
00586 }