//============================================================================== // This is The main code to input function to read inputs from the Joystick and then //process any commands. //============================================================================== void JoystickInputController::ControlInput(void) { // See if we have a new command available... if(ljoy.readMsgs() > 0) { boolean fAdjustLegPositions = false; short sLegInitXZAdjust = 0; short sLegInitAngleAdjust = 0; // See if this is the first message we have received if (g_ulLastMsgTime == (unsigned long)-1) { // First valid message see if we can figure out what it is from... printf("Firt JS0 even: %d axes %d buttons Name: %s\n", ljoy.joystickAxisCount(), ljoy.joystickButtonCount(), ljoy.JoystickName()); if ((ljoy.joystickAxisCount() == 27) && (ljoy.joystickButtonCount() == 19)) { printf("PS3!\n"); } else if ((ljoy.joystickAxisCount() == 8) && (ljoy.joystickButtonCount() == 14)) { printf("DS4!\n"); } } // Save message time so we may detect timeouts. g_ulLastMsgTime = millis(); // We have a message see if we have turned the robot on or not... if (ljoy.buttonPressed(JOYSTICK_BUTTONS::START_SHARE)) { if (!g_InControlState.fRobotOn) { // Turn it on g_InControlState.fRobotOn = true; fAdjustLegPositions = true; printf("Turn Robot on: %d %d : %d %d\n", ljoy.axis(JOYSTICK_AXES::LX), ljoy.axis(JOYSTICK_AXES::LY), ljoy.axis(JOYSTICK_AXES::RX), ljoy.axis(JOYSTICK_AXES::RY)); } else { ControllerTurnRobotOff(); } } // Few of the buttons we may process even when off... if (ljoy.buttonPressed(JOYSTICK_BUTTONS::L3)) g_fDebugOutput = !g_fDebugOutput; // toggle debug on and off // If robot is not on, lets bail from here... if ( !g_InControlState.fRobotOn) return; // In some cases we update values as to keep other places to use the values // So we create a local copy we use through this function. int axes_rx = ljoy.axis(JOYSTICK_AXES::RX); int axes_ry = ljoy.axis(JOYSTICK_AXES::RY); int axes_lx = ljoy.axis(JOYSTICK_AXES::LX); int axes_ly = ljoy.axis(JOYSTICK_AXES::LY); // Experimenting with trying to detect when IDLE. maybe set a state of // of no button pressed and all joysticks are in the DEADBAND area... g_InControlState.fControllerInUse = ljoy.buttons() || (abs((axes_lx/256)) >= cTravelDeadZone) || (abs((axes_ly/256)) >= cTravelDeadZone) || (abs((axes_rx/256)) >= cTravelDeadZone) || (abs((axes_ry/256)) >= cTravelDeadZone); // [SWITCH MODES] // Cycle through modes... // May break this up, like PS2... if (ljoy.buttonPressed(JOYSTICK_BUTTONS::R1)) { if (++ControlMode >= MODECNT) { ControlMode = WALKMODE; // cycled back around... MSound( 2, 50, 2000, 50, 3000); } else { MSound( 1, 50, 2000); } } // Hack make easy to get back to standard mode... if (ljoy.buttonPressed(JOYSTICK_BUTTONS::PS)) { ControlMode = WALKMODE; // cycled back around... MSound( 2, 50, 2000, 50, 3000); } //[Common functions] //Switch Balance mode on/off if (ljoy.buttonPressed(JOYSTICK_BUTTONS::SQUARE)) { g_InControlState.BalanceMode = !g_InControlState.BalanceMode; if (g_InControlState.BalanceMode) { MSound( 1, 250, 1500); } else { MSound( 2, 100, 2000, 50, 4000); } } //Stand up, sit down if (ljoy.buttonPressed(JOYSTICK_BUTTONS::TRI)) { if (g_BodyYOffset>0) g_BodyYOffset = 0; else g_BodyYOffset = 35; fAdjustLegPositions = true; g_fDynamicLegXZLength = false; } // We will use L1 with the Right joystick to control both body offset as well as Speed... // We move each pass through this by a percentage of how far we are from center in each direction // We get feedback with height by seeing the robot move up and down. For Speed, I put in sounds // which give an idea, but only for those whoes robot has a speaker if (ljoy.button(JOYSTICK_BUTTONS::L1)) { // raise or lower the robot on the joystick up /down int delta = (axes_ry/256)/25; if (delta) { g_BodyYOffset = max(min(g_BodyYOffset + delta, MAX_BODY_Y), 0); fAdjustLegPositions = true; } // Likewise for Speed control int dspeed = (axes_rx/256) / 16; // if ((dspeed < 0) && g_InControlState.SpeedControl) { if ((word)(-dspeed) < g_InControlState.SpeedControl) g_InControlState.SpeedControl += dspeed; else g_InControlState.SpeedControl = 0; MSound( 1, 50, 1000+g_InControlState.SpeedControl); } if ((dspeed > 0) && (g_InControlState.SpeedControl < 2000)) { g_InControlState.SpeedControl += dspeed; if (g_InControlState.SpeedControl > 2000) g_InControlState.SpeedControl = 2000; MSound( 1, 50, 1000+g_InControlState.SpeedControl); } // Likewise we use the left Joystick to control Postion of feet sLegInitXZAdjust = axes_lx/(256*10); // play with this. #ifdef ADJUSTABLE_LEG_ANGLES sLegInitAngleAdjust = axes_ly/(256*8); #endif // Make sure other areas of code below does not use some of the joystick values axes_lx = 0; axes_ly = 0; axes_rx = 0; // don't walk when adjusting the speed here... } //[Walk functions] if (ControlMode == WALKMODE) { //Switch gates if ((ljoy.buttonPressed(JOYSTICK_BUTTONS::SELECT_OPT)) //No movement && abs(g_InControlState.TravelLength.x)<cTravelDeadZone && abs(g_InControlState.TravelLength.z)<cTravelDeadZone && abs(g_InControlState.TravelLength.y*2)<cTravelDeadZone ) { // Go to the next gait... g_InControlState.GaitType = g_InControlState.GaitType+1; // Make sure we did not exceed number of gaits... if (g_InControlState.GaitType<NUM_GAITS) { #ifndef OPT_ESPEAK MSound( 1, 50, 2000); #endif } else { #ifdef OPT_ESPEAK MSound (2, 50, 2000, 50, 2250); #endif g_InControlState.GaitType = 0; } #ifdef OPT_ESPEAK SpeakStr(s_asGateNames[g_InControlState.GaitType]); #endif GaitSelect(); } //Double leg lift height if (ljoy.buttonPressed(JOYSTICK_BUTTONS::R2)) { MSound( 1, 50, 2000); // wrap around mode HeightSpeedMode = (HeightSpeedMode + 1) & 0x3; DoubleTravelOn = HeightSpeedMode & 0x1; if ( HeightSpeedMode & 0x2) g_InControlState.LegLiftHeight = 80; else g_InControlState.LegLiftHeight = 50; } // Switch between Walk method 1 && Walk method 2 if (ljoy.buttonPressed(JOYSTICK_BUTTONS::R3)) { MSound (1, 50, 2000); WalkMethod = !WalkMethod; } //Walking if (WalkMethod) //(Walk Methode) //Right Stick Up/Down g_InControlState.TravelLength.z = ((axes_ry/256)); else { g_InControlState.TravelLength.x = -(axes_lx/256); g_InControlState.TravelLength.z = (axes_ly/256); } if (!DoubleTravelOn) //(Double travel length) { g_InControlState.TravelLength.x = g_InControlState.TravelLength.x/2; g_InControlState.TravelLength.z = g_InControlState.TravelLength.z/2; } //Right Stick Left/Right g_InControlState.TravelLength.y = -((axes_rx/256))/4; } //[Translate functions] g_BodyYShift = 0; if (ControlMode == TRANSLATEMODE) { g_InControlState.BodyPos.x = SmoothControl((((axes_lx/256))*2/3), g_InControlState.BodyPos.x, SmDiv); g_InControlState.BodyPos.z = SmoothControl((((axes_ly/256))*2/3), g_InControlState.BodyPos.z, SmDiv); g_InControlState.BodyRot1.y = SmoothControl((((axes_rx/256))*2), g_InControlState.BodyRot1.y, SmDiv); g_BodyYShift = (-((axes_ry/256))/2); } //[Rotate functions] if (ControlMode == ROTATEMODE) { g_InControlState.BodyRot1.x = ((axes_ly/256)); g_InControlState.BodyRot1.y = ((axes_rx/256))*2; g_InControlState.BodyRot1.z = ((axes_lx/256)); g_BodyYShift = (-((axes_ry/256))/2); } //Calculate walking time delay g_InControlState.InputTimeDelay = 128 - max(max(abs((axes_lx/256)), abs((axes_ly/256))), abs((axes_rx/256))); //Calculate g_InControlState.BodyPos.y g_InControlState.BodyPos.y = max(g_BodyYOffset + g_BodyYShift, 0); // Add Dynamic leg position and body height code if (sLegInitXZAdjust || sLegInitAngleAdjust) { // User asked for manual leg adjustment - only do when we have finished any previous adjustment if (!g_InControlState.ForceGaitStepCnt) { if (sLegInitXZAdjust) g_fDynamicLegXZLength = true; sLegInitXZAdjust += GetLegsXZLength(); // Add on current length to our adjustment... // Handle maybe change angles... #ifdef ADJUSTABLE_LEG_ANGLES if (sLegInitAngleAdjust) RotateLegInitAngles(sLegInitAngleAdjust); #endif // Give system time to process previous calls AdjustLegPositions(sLegInitXZAdjust); } } if (fAdjustLegPositions && !g_fDynamicLegXZLength) AdjustLegPositionsToBodyHeight(); // Put main workings into main program file } else { // We did not receive a valid packet. check for a timeout to see if we should turn robot off... if (g_InControlState.fRobotOn) { if (! ljoy.connected()) // See if controller is still connected? { g_InControlState.fControllerInUse = true; // make sure bypass is not used. ControllerTurnRobotOff(); } } } }
//============================================================================== // This is The main code to input function to read inputs from the Commander and then //process any commands. //============================================================================== void CommanderInputController::ControlInput(void) { // See if we have a new command available... if(command.ReadMsgs() > 0) { // If we receive a valid message than turn robot on... g_InControlState.fRobotOn = true; // Experimenting with trying to detect when IDLE. maybe set a state of // of no button pressed and all joysticks are in the DEADBAND area... g_InControlState.fControllerInUse = command.buttons || (abs(command.leftH) >= cTravelDeadZone) || (abs(command.leftV) >= cTravelDeadZone) || (abs(command.rightH) >= cTravelDeadZone) || (abs(command.rightV) >= cTravelDeadZone); // [SWITCH MODES] // Cycle through modes... if ((command.buttons & BUT_LT) && !(buttonsPrev & BUT_LT)) { if (++ControlMode >= MODECNT) { ControlMode = WALKMODE; // cycled back around... MSound( 2, 50, 2000, 50, 3000); } else { MSound( 1, 50, 2000); } } //[Common functions] //Switch Balance mode on/off if ((command.buttons & BUT_L4) && !(buttonsPrev & BUT_L4)) { g_InControlState.BalanceMode = !g_InControlState.BalanceMode; if (g_InControlState.BalanceMode) { MSound( 1, 250, 1500); } else { MSound( 2, 100, 2000, 50, 4000); } } //Stand up, sit down if ((command.buttons & BUT_L5) && !(buttonsPrev & BUT_L5)) { if (g_BodyYOffset>0) g_BodyYOffset = 0; else g_BodyYOffset = 35; } // We will use L6 with the Right joystick to control both body offset as well as Speed... // We move each pass through this by a percentage of how far we are from center in each direction // We get feedback with height by seeing the robot move up and down. For Speed, I put in sounds // which give an idea, but only for those whoes robot has a speaker if (command.buttons & BUT_L6 ) { printf("L6 down\n\r"); // raise or lower the robot on the joystick up /down // Maybe should have Min/Max g_BodyYOffset += command.rightV/25; if (abs(command.rightV)>= 25) printf("%d %d", g_BodyYOffset, command.rightV); // Likewise for Speed control int dspeed = command.rightH / 16; // if ((dspeed < 0) && g_InControlState.SpeedControl) { if ((word)(-dspeed) < g_InControlState.SpeedControl) g_InControlState.SpeedControl += dspeed; else g_InControlState.SpeedControl = 0; MSound( 1, 50, 1000+g_InControlState.SpeedControl); } if ((dspeed > 0) && (g_InControlState.SpeedControl < 2000)) { g_InControlState.SpeedControl += dspeed; if (g_InControlState.SpeedControl > 2000) g_InControlState.SpeedControl = 2000; MSound( 1, 50, 1000+g_InControlState.SpeedControl); } command.rightH = 0; // don't walk when adjusting the speed here... } //[Walk functions] if (ControlMode == WALKMODE) { //Switch gates if (((command.buttons & BUT_R1) && !(buttonsPrev & BUT_R1)) //No movement && abs(g_InControlState.TravelLength.x)<cTravelDeadZone && abs(g_InControlState.TravelLength.z)<cTravelDeadZone && abs(g_InControlState.TravelLength.y*2)<cTravelDeadZone ) { // Go to the next gait... g_InControlState.GaitType = g_InControlState.GaitType+1; // Make sure we did not exceed number of gaits... if (g_InControlState.GaitType<NUM_GAITS) { #ifndef OPT_ESPEAK MSound( 1, 50, 2000); #endif } else { #ifdef OPT_ESPEAK MSound (2, 50, 2000, 50, 2250); #endif g_InControlState.GaitType = 0; } #ifdef OPT_ESPEAK SpeakStr(s_asGateNames[g_InControlState.GaitType]); #endif GaitSelect(); } //Double leg lift height if ((command.buttons & BUT_RT) && !(buttonsPrev & BUT_RT)) { MSound( 1, 50, 2000); // wrap around mode HeightSpeedMode = (HeightSpeedMode + 1) & 0x3; DoubleTravelOn = HeightSpeedMode & 0x1; if ( HeightSpeedMode & 0x2) g_InControlState.LegLiftHeight = 80; else g_InControlState.LegLiftHeight = 50; } // Switch between Walk method 1 && Walk method 2 if ((command.buttons & BUT_R2) && !(buttonsPrev & BUT_R2)) { MSound (1, 50, 2000); WalkMethod = !WalkMethod; } //Walking if (WalkMethod) //(Walk Methode) //Right Stick Up/Down g_InControlState.TravelLength.z = (command.rightV); else { g_InControlState.TravelLength.x = -command.leftH; g_InControlState.TravelLength.z = command.leftV; } if (!DoubleTravelOn) //(Double travel length) { g_InControlState.TravelLength.x = g_InControlState.TravelLength.x/2; g_InControlState.TravelLength.z = g_InControlState.TravelLength.z/2; } //Right Stick Left/Right g_InControlState.TravelLength.y = -(command.rightH)/4; } //[Translate functions] g_BodyYShift = 0; if (ControlMode == TRANSLATEMODE) { g_InControlState.BodyPos.x = SmoothControl(((command.leftH)*2/3), g_InControlState.BodyPos.x, SmDiv); g_InControlState.BodyPos.z = SmoothControl(((command.leftV)*2/3), g_InControlState.BodyPos.z, SmDiv); g_InControlState.BodyRot1.y = SmoothControl(((command.rightH)*2), g_InControlState.BodyRot1.y, SmDiv); // g_InControlState.BodyPos.x = (command.leftH)/2; // g_InControlState.BodyPos.z = -(command.leftV)/3; // g_InControlState.BodyRot1.y = (command.rightH)*2; g_BodyYShift = (-(command.rightV)/2); } //[Rotate functions] if (ControlMode == ROTATEMODE) { g_InControlState.BodyRot1.x = (command.leftV); g_InControlState.BodyRot1.y = (command.rightH)*2; g_InControlState.BodyRot1.z = (command.leftH); g_BodyYShift = (-(command.rightV)/2); } #ifdef OPT_GPPLAYER //[GPPlayer functions] if (ControlMode == 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) || (command.rightV > 16) || (command.rightV < -16)) { // We are in speed modify mode... if (command.rightV >= 0) g_sGPSMController = map(command.rightV, 0, 127, 0, 200); else g_sGPSMController = map(command.rightV, -127, 0, -200, 0); g_ServoDriver.GPSetSpeedMultiplyer(g_sGPSMController); } } //Switch between sequences if ((command.buttons & BUT_R1) && !(buttonsPrev & BUT_R1)) { if (!g_ServoDriver.FIsGPSeqActive() ) { if (GPSeq < 5) //Max sequence { MSound (1, 50, 1500); GPSeq = GPSeq+1; } else { MSound (2, 50, 2000, 50, 2250); GPSeq=0; } } } //Start Sequence if ((command.buttons & BUT_R2) && !(buttonsPrev & BUT_R2)) { if (!g_ServoDriver.FIsGPSeqActive() ) { g_ServoDriver.GPStartSeq(GPSeq); g_sGPSMController = 32767; // Say that we are not in Speed modify mode yet... valid ranges are 50-200 (both postive and negative... } else { // tell the GP system to abort if possible... g_ServoDriver.GPStartSeq(0xff); MSound (2, 50, 2000, 50, 2000); } } } #endif // OPT_GPPLAYER //Calculate walking time delay g_InControlState.InputTimeDelay = 128 - max(max(abs(command.leftH), abs(command.leftV)), abs(command.rightH)); //Calculate g_InControlState.BodyPos.y g_InControlState.BodyPos.y = max(g_BodyYOffset + g_BodyYShift, 0); // Save away the buttons state as to not process the same press twice. buttonsPrev = command.buttons; extPrev = command.ext; g_ulLastMsgTime = millis(); } else { // We did not receive a valid packet. check for a timeout to see if we should turn robot off... if (g_InControlState.fRobotOn) { if ((millis() - g_ulLastMsgTime) > ARBOTIX_TO) { g_InControlState.fControllerInUse = true; // make sure bypass is not used. CommanderTurnRobotOff(); } } } }
//============================================================================== // 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 }