|
5DT Data Glove plugin 1.0
|
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(¤tTime); 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(¤tTime); 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 }
1.7.3