/*------------------------------------------------------------------------------------------------------------- UTLGetInitialPairs -------------------------------------------------------------------------------------------------------------*/ int UTLGetInitialPairs(const Minutia pminR[], const int nRCnt, const Minutia pminT[], const int nTCnt, Pair pPairs[]) { int i = 0; int j = 0; RMinutia rminR[MAX_MINUTIAE]; RMinutia rminT[MAX_MINUTIAE]; /*sanity check*/ if(pminR == NULL || nRCnt < 1 || pminT == NULL || nTCnt < 1 || pPairs == NULL) return UTL_ERR_INVALID_PARAMETER; /* test matching hypotheses */ for(i=0;i<nRCnt;i++) { UTLConvertToRadial(pminR,nRCnt,pminR[i].m_nX,pminR[i].m_nY,pminR[i].m_nTheta,rminR); for(j=0;j<nTCnt;j++) { UTLConvertToRadial(pminT,nTCnt,pminT[j].m_nX,pminT[j].m_nY,pminT[j].m_nTheta,rminT); DBGPrintf("----------------------------------------------------\n"); DBGPrintf("MatchMinutiaSets: Hypothesis (%d,%d)->(%d,%d)\n",pminR[i].m_nX,pminR[i].m_nY,pminT[j].m_nX,pminT[j].m_nY); DBGPrintf("----------------------------------------------------\n"); UTLMatchRadial(rminR,nRCnt,rminT,nRCnt,pPairs); } } UTLSortPairs(pPairs,nRCnt*nTCnt); DBGPrintPairs(pminR,nRCnt,pminT,nRCnt,pPairs); return UTL_ERR_NO_ERROR; }
/*------------------------------------------------------------------------------------------------------------- UTLConvertToRadial -------------------------------------------------------------------------------------------------------------*/ int UTLMatchRadial(const RMinutia pRMin[], const int nRCnt, const RMinutia pTMin[], const int nTCnt,Pair pPair[]) { int i = 0; int j = 0; double dR = 0; double dTheta = 0; double dDelta = 0; int nAbs = 0; int nTFlags[MAX_MINUTIAE] ={0}; int nRFlags[MAX_MINUTIAE] ={0}; for(i=0;i<nRCnt;i++) { /*skip far away points*/ if(pRMin[i].m_dR > MAX_R) continue; for(j=0;j<nTCnt;j++) { if(nTFlags[j]) /*already matched*/ continue; /*skip far away points*/ if(pTMin[j].m_dR > MAX_R) continue; /*check for match*/ dR = fabs(log10((pRMin[i].m_dR+1e-5)/(pTMin[j].m_dR+1e-5))); if(dR > DR) /*no match*/ continue; nAbs = abs(pRMin[i].m_nTheta - pTMin[j].m_nTheta); if((360-nAbs) < nAbs) dTheta = (360-nAbs); else dTheta = nAbs; if(dTheta > DTHETA) /*no match*/ continue; nAbs = abs(pRMin[i].m_nDelta - pTMin[j].m_nDelta); if((360-nAbs) < nAbs) dDelta = (360-nAbs); else dDelta = nAbs; if(dDelta > DDELTA) /*no match*/ continue; if(!nRFlags[i] && !nTFlags[j]) /*match found*/ { nRFlags[i] = 1; nTFlags[j] = 1; //add vote to pair matrix pPair[i*nTCnt+j].m_dScore++; pPair[i*nTCnt+j].m_nRIdx = i; pPair[i*nTCnt+j].m_nTIdx = j; DBGPrintf("Radial Match: [%d,%d]->(%lf,%d,%d),(%lf,%d,%d)\n",i,j,pRMin[i].m_dR,pRMin[i].m_nTheta,pRMin[i].m_nDelta, pTMin[j].m_dR,pTMin[j].m_nTheta,pTMin[j].m_nDelta); } } } return UTL_ERR_NO_ERROR; }
//============================================================================== // This is code the checks for and processes input from the DIY XBee receiver // work //============================================================================== void DIYXBeeController::ControlInput(void) { byte iNumButton; // Then try to receive a packet of information from the XBEE. // It will return true if it has a valid packet if (ReceiveXBeePacket(&g_diyp)) { if (memcmp((void*)&g_diyp, (void*)&g_diypPrev, sizeof(g_diyp)) != 0) { #ifdef XBEE_NEW_DATA_ONLY if (g_diystate.fPacketForced) SendXbeeNewDataOnlyPacket(1); #endif #ifdef DEBUG // setup to output back to our USB port if (g_fDebugOutput) { DBGPrintf("%x - %d %d - %d %d - %d %d\n", g_diyp.s.wButtons, g_diyp.s.bRJoyLR, g_diyp.s.bRJoyUD, g_diyp.s.bLJoyLR, g_diyp.s.bLJoyUD, g_diyp.s.bRSlider, g_diyp.s.bLSlider); } #endif } // OK lets try "0" button for Start. if ((g_diyp.s.wButtons & (1<<0)) && ((g_diypPrev.s.wButtons & (1<<0)) == 0)) { //Start Button (0 on keypad) test if(g_InControlState.fHexOn) { //Turn off g_InControlState.BodyPos.x = 0; g_InControlState.BodyPos.y = 0; g_InControlState.BodyPos.z = 0; g_InControlState.BodyRot1.x = 0; g_InControlState.BodyRot1.y = 0; g_InControlState.BodyRot1.z = 0; g_InControlState.TravelLength.x = 0; g_InControlState.TravelLength.z = 0; g_InControlState.TravelLength.y = 0; g_BodyYOffset = 0; g_BodyYSift = 0; g_InControlState.SelectedLeg = 255; g_InControlState.fHexOn = 0; } else { //Turn on g_InControlState.fHexOn = 1; } } if (g_InControlState.fHexOn) { if ((g_diyp.s.wButtons & (1<<0xa)) && ((g_diypPrev.s.wButtons & (1<<0xa)) == 0)) { // A button test MSound(1, 50, 2000); XBeePlaySounds(1, 50, 2000); bXBeeControlMode = WALKMODE; XBeeOutputStringF(F("Walking")); } if ((g_diyp.s.wButtons & (1<<0xb)) && ((g_diypPrev.s.wButtons & (1<<0xb)) == 0)) { // B button test MSound(1, 50, 2000); XBeePlaySounds(1, 50, 2000); bXBeeControlMode = TRANSLATEMODE; XBeeOutputStringF(F("Body Translate")); } if ((g_diyp.s.wButtons & (1<<0xc)) && ((g_diypPrev.s.wButtons & (1<<0xc)) == 0)) { // C button test MSound(1, 50, 2000); bXBeeControlMode = ROTATEMODE; XBeeOutputStringF(F("Body Rotate")); } if ((g_diyp.s.wButtons & (1<<0xD)) && ((g_diypPrev.s.wButtons & (1<<0xd)) == 0)) { // D button test - Single Leg MSound(1, 50, 2000); if (g_InControlState.SelectedLeg==255) // none g_InControlState.SelectedLeg=cRF; else if (bXBeeControlMode==SINGLELEGMODE) //Double press to turn all legs down g_InControlState.SelectedLeg=255; //none bXBeeControlMode=SINGLELEGMODE; XBeeOutputStringF (F("Single Leg")); } if ((g_diyp.s.wButtons & (1<<0xe)) && ((g_diypPrev.s.wButtons & (1<<0xe)) == 0)) { // E button test - Balance mode if (!g_InControlState.BalanceMode) { g_InControlState.BalanceMode = 1; MSound( 2, 100, 2000, 50, 4000); XBeePlaySounds(2, 100, 2000, 50, 4000); XBeeOutputStringF(F("Balance On")); } else { g_InControlState.BalanceMode = 0; MSound( 1, 250, 1500); XBeePlaySounds(1, 50, 1500); XBeeOutputStringF(F("Balance Off")); } } #ifdef OPT_GPPLAYER if ((g_diyp.s.wButtons & (1<<0xf)) && ((g_diypPrev.s.wButtons & (1<<0xf)) == 0)) { // F button test - GP Player if (g_ServoDriver.FIsGPEnabled()) { //F Button GP Player Mode Mode on/off -- SSC supports this mode XBeeOutputStringF(F("Run Sequence")); MSound(1, 50, 2000); g_InControlState.BodyPos.x = 0; g_InControlState.BodyPos.z = 0; g_InControlState.BodyRot1.x = 0; g_InControlState.BodyRot1.y = 0; g_InControlState.BodyRot1.z = 0; g_InControlState.TravelLength.x = 0; g_InControlState.TravelLength.z = 0; g_InControlState.TravelLength.y = 0; g_InControlState.SelectedLeg=255; //none g_InControlState.fSLHold=0; bXBeeControlMode = GPPLAYERMODE; } else { XBeeOutputStringF(F("Seq Disabled")); MSound(1, 50, 2000); } } #endif //Hack there are several places that use the 1-N buttons to select a number as an index // so lets convert our bitmap of which key may be pressed to a number... // BUGBUG:: There is probably a cleaner way to convert... Will extract buttons 1-9 iNumButton = 0; // assume no button if ((g_diyp.s.wButtons & 0x3fe) && ((g_diypPrev.s.wButtons & 0x3fe) == 0)) { // buttons 1-9 word w = g_diyp.s.wButtons & 0x3fe; while ((w & 0x1) == 0) { w >>= 1; iNumButton++; } } // BUGBUG:: we are using all keys now, may want to reserve some... //Switch gait // We will do slightly different here than the RC version as we have a bit per button if ((bXBeeControlMode==WALKMODE) && iNumButton && (iNumButton <= NUM_GAITS)) { //1-8 Button Gait select if ( abs(g_InControlState.TravelLength.x)<cTravelDeadZone && abs(g_InControlState.TravelLength.z)<cTravelDeadZone && abs(g_InControlState.TravelLength.y*2)<cTravelDeadZone) { //Switch Gait type MSound( 1, 50, 2000); //Sound P9, [50\4000] g_InControlState.GaitType = iNumButton-1; #ifdef DEBUG DBGPrintf("New Gate: %d\n\r", g_InControlState.GaitType); #endif GaitSelect(); #ifdef DEBUG DBGPrintf("Output Gate Named\n\r"); #endif XBeeOutputStringF((const __FlashStringHelper *)pgm_read_word(&s_asGateNames[g_InControlState.GaitType])); } } //Switch single leg if (bXBeeControlMode==SINGLELEGMODE) { if (iNumButton>=1 && iNumButton<=6) { MSound( 1, 50, 2000); //Sound P9, [50\4000] g_InControlState.SelectedLeg = iNumButton-1; g_InControlState.fSLHold=0; } if (iNumButton == 9) { //Switch Directcontrol MSound( 1, 50, 2000); //Sound P9, [50\4000] g_InControlState.fSLHold ^= 1; //Toggle g_InControlState.fSLHold } } else if (bXBeeControlMode==WALKMODE) { g_InControlState.SelectedLeg=255; // none g_InControlState.fSLHold=0; } //Body Height - Control depends on how big our packet was (ie which controller we are using) if (g_diystate.cbPacketSize > PKT_MSLIDER) g_InControlState.BodyPos.y = SmoothControl((g_diyp.s.bMSlider / 2), g_InControlState.BodyPos.y, SmDiv); else if (g_diystate.cbPacketSize > PKT_LPOT) g_InControlState.BodyPos.y = SmoothControl((g_diyp.s.bLPot*2/3), g_InControlState.BodyPos.y, SmDiv);//Zenta test else g_InControlState.BodyPos.y = SmoothControl((g_diyp.s.bLJoyUD / 2), g_InControlState.BodyPos.y, SmDiv); //Leg lift height - Right slider has value 0-255 translate to 30-93 g_InControlState.LegLiftHeight = 30 + g_diyp.s.bRSlider/3;//Zenta trying 3 instead of 4 //--------------------------------------------------------------------------------------------------- //Walk mode //--------------------------------------------------------------------------------------------------- if (bXBeeControlMode==WALKMODE) { // Kurt's Arduino version if (g_diystate.cbPacketSize > PKT_MSLIDER) { g_InControlState.TravelLength.x = -(g_diyp.s.bLJoyLR - 128); g_InControlState.TravelLength.z = -(g_diyp.s.bLJoyUD - 128) ; g_InControlState.TravelLength.y = -(g_diyp.s.bRJoyLR - 128)/3; //g_InControlState.BodyRot1.x = SmoothControl(((bPacket(PKT_RJOYUD)-128)*2), g_InControlState.BodyRot1.x, 2); //g_InControlState.BodyRot1.z = SmoothControl((-(bPacket(PKT_RPOT)-128)*2), g_InControlState.BodyRot1.z, 2); g_InControlState.InputTimeDelay = 128 - max( max( abs(g_diyp.s.bLJoyLR-128), abs(g_diyp.s.bLJoyUD-128)), abs(g_diyp.s.bRJoyLR-128)) + (128 -(g_diyp.s.bLSlider)/2); } else if (g_diystate.cbPacketSize > PKT_LPOT) { // Case for original DIY XBee with extra pots g_InControlState.TravelLength.x = -(g_diyp.s.bLJoyLR - 128); g_InControlState.TravelLength.z = -(g_diyp.s.bLJoyUD - 128) ; g_InControlState.TravelLength.y = -(g_diyp.s.bRJoyLR - 128)/3; g_InControlState.BodyRot1.z = SmoothControl((-(g_diyp.s.bRPot-128)*2), g_InControlState.BodyRot1.z, SmDiv); g_InControlState.InputTimeDelay = 128 - max( max( abs(g_diyp.s.bLJoyLR-128), abs(g_diyp.s.bLJoyUD-128)), abs(g_diyp.s.bRJoyLR-128)) + (128 -(g_diyp.s.bLSlider)/2); } else { // original DIY XBee g_InControlState.TravelLength.x = -(g_diyp.s.bRJoyLR - 128); g_InControlState.TravelLength.z = -(g_diyp.s.bRJoyUD - 128) ; g_InControlState.TravelLength.y = -(g_diyp.s.bLJoyLR - 128)/3; g_InControlState.InputTimeDelay = 128 - max( max( abs(g_diyp.s.bRJoyLR-128), abs(g_diyp.s.bRJoyUD-128)), abs(g_diyp.s.bLJoyLR-128)) + (128 -(g_diyp.s.bLSlider)/2); } } //--------------------------------------------------------------------------------------------------- //Body move //--------------------------------------------------------------------------------------------------- if (bXBeeControlMode==TRANSLATEMODE) { if (g_diystate.cbPacketSize > PKT_LPOT) { g_InControlState.BodyPos.x = SmoothControl(((g_diyp.s.bRJoyLR-128)*2/3), g_InControlState.BodyPos.x, SmDiv); g_InControlState.BodyPos.z = SmoothControl(((g_diyp.s.bRJoyUD-128)*2/3), g_InControlState.BodyPos.z, SmDiv); g_InControlState.BodyRot1.y = SmoothControl(((g_diyp.s.bLJoyLR-128)*2), g_InControlState.BodyRot1.y, SmDiv); } else { g_InControlState.BodyPos.x = SmoothControl(((g_diyp.s.bRJoyLR-128)*2/3), g_InControlState.BodyPos.x, SmDiv); g_InControlState.BodyPos.z = SmoothControl(((g_diyp.s.bRJoyUD-128)*2/3), g_InControlState.BodyPos.z, SmDiv); g_InControlState.BodyRot1.y = SmoothControl(((g_diyp.s.bLJoyLR-128)*2), g_InControlState.BodyRot1.y, SmDiv); } g_InControlState.InputTimeDelay = 128 - abs(g_diyp.s.bLJoyUD-128) + (128 -(g_diyp.s.bLSlider)/2); } //--------------------------------------------------------------------------------------------------- //Body rotate //--------------------------------------------------------------------------------------------------- if (bXBeeControlMode==ROTATEMODE) { if (iNumButton &&(iNumButton <=3)) { LjoyUDFunction = iNumButton -1; MSound( 1, 20, 2000); XBeeOutputStringF((const __FlashStringHelper *)pgm_read_word(&s_asLJoyUDNames[LjoyUDFunction])); } if (iNumButton == 4) { // Toogle Left Joystick left/Right function LeftJoyLRmode = !LeftJoyLRmode; if (LeftJoyLRmode) { XBeeOutputStringF(F("LJOYLR trans")); MSound( 1, 20, 1000); } else { XBeeOutputStringF(F("LJOYLR rotate")); MSound( 1, 20, 2000); } } #ifdef DISP_VOLTAGE if (iNumButton == 8) { // Toogle g_fDisplayLiPo g_fDisplayLiPo = !g_fDisplayLiPo; MSound( 1, 20, 1500+500*g_fDisplayLiPo); } #endif if (iNumButton == 9) { // Toogle LockFunction LockFunction = !LockFunction; if (LockFunction) { XBeeOutputStringF(F("Lock ON")); MSound( 1, 20, 1500); } else { XBeeOutputStringF(F("Lock OFF")); MSound( 1, 20, 2500); } } // BranchLJoyUDFunction in basic switch (LjoyUDFunction) { case 0: g_InControlState.TravelLength.z = -(g_diyp.s.bLJoyUD-128); // dito need to update break; case 1: g_InControlState.BodyPos.z = SmoothControl(((g_diyp.s.bLJoyUD-128)*2/3), g_InControlState.BodyPos.z, SmDiv); break; default: if (!LockFunction) { g_InControlState.BodyRotOffset.z = (g_diyp.s.bLJoyUD - 128); g_InControlState.BodyRotOffset.y = (g_diyp.s.bRPot - 128); } } if (LeftJoyLRmode) {//;Do X translation: g_InControlState.BodyPos.x = SmoothControl(((g_diyp.s.bLJoyLR-128)*2/3), g_InControlState.BodyPos.x, SmDiv); } else { g_InControlState.BodyRot1.y = SmoothControl (((g_diyp.s.bLJoyLR-128)*2), g_InControlState.BodyRot1.y, SmDiv); } g_InControlState.BodyRot1.x = SmoothControl(((g_diyp.s.bRJoyUD-128)*2), g_InControlState.BodyRot1.x, SmDiv); g_InControlState.BodyRot1.z = SmoothControl((-(g_diyp.s.bRJoyLR-128)*2), g_InControlState.BodyRot1.z , SmDiv); g_InControlState.InputTimeDelay = 128 - abs(g_diyp.s.bLJoyUD-128) + (128 -(g_diyp.s.bLSlider)/2); } //--------------------------------------------------------------------------------------------------- //Single Leg Mode //--------------------------------------------------------------------------------------------------- if (bXBeeControlMode == SINGLELEGMODE) { g_InControlState.SLLeg.x = SmoothControl(((g_diyp.s.bRJoyLR-128)), g_InControlState.SLLeg.x , SmDiv);//; g_InControlState.SLLeg.z = SmoothControl((-(g_diyp.s.bRJoyUD-128)), g_InControlState.SLLeg.z , SmDiv);//; g_InControlState.SLLeg.y = SmoothControl((-(g_diyp.s.bLJoyUD-128)), g_InControlState.SLLeg.y , SmDiv);//Need to check packetsize.. g_InControlState.InputTimeDelay = 128 - max( max( abs(g_diyp.s.bRJoyLR-128), abs(g_diyp.s.bRJoyUD-128)), abs(g_diyp.s.bLJoyLR-128)) + (128 -(g_diyp.s.bLSlider)/2); } //--------------------------------------------------------------------------------------------------- // Sequence General Player Mode //--------------------------------------------------------------------------------------------------- #ifdef OPT_GPPLAYER if (bXBeeControlMode == GPPLAYERMODE) { // Lets try some speed control... Map all values if we have mapped some before // or start mapping if we exceed some minimum delta from center // Have to keep reminding myself that commander library already subtracted 128... if (g_ServoDriver.FIsGPSeqActive() ) { if ((g_sGPSMController != 32767) || (g_diyp.s.bRJoyUD > (128+16)) || (g_diyp.s.bRJoyUD < (128-16))) { // We are in speed modify mode... short sNewGPSM = map(g_diyp.s.bRJoyUD, 0, 255, -200, 200); if (sNewGPSM != g_sGPSMController) { g_sGPSMController = sNewGPSM; g_ServoDriver.GPSetSpeedMultiplyer(g_sGPSMController); } } // See what step we are on, if it changed then output the step to the user byte bCurStep = g_ServoDriver.GPCurStep(); if (bCurStep != g_bGPCurStepPrev) { g_bGPCurStepPrev = bCurStep; // Lets build a quick and dirty string to output char szTemp[20]; sprintf(szTemp, "cs: %d SM: %d", bCurStep, (g_sGPSMController == 32767) ? 100 : g_sGPSMController); XBeeOutputString(szTemp); } } if (iNumButton>=1 && iNumButton<=9) { //1-9 Button Play GP Seq word wGPSeqPtr; if (!g_ServoDriver.FIsGPSeqActive() ) { uint8_t GPSeq = iNumButton-1; if ( g_ServoDriver.FIsGPSeqDefined(GPSeq)) { XBeeOutputStringF(F("Start Sequence")); // Tell user sequence started. g_ServoDriver.GPStartSeq(GPSeq); g_sGPSMController = 32767; // Say we are not in modifiy speed modifier mode yet... g_bGPCurStepPrev = 0xff; } else { XBeeOutputStringF(F("Seq Not defined")); // that sequence was not defined... } } else { // Cancel the current one g_ServoDriver.GPStartSeq(0xff); // tell the GP system to abort if possible... MSound (2, 50, 2000, 50, 2000); } } } #endif //Calculate walking time delay } g_diypPrev = g_diyp; // remember the last packet }