# Strafe using Joystick Buttons

I’m sure there’s probably a thread out there already about this question, but I’m having problems finding it. Anyway, I have programmed (using LabView) our robot to drive tank style using mecanum wheels, but I would also like to program it to strafe left and right using buttons #4 and #5 on the joystick. I would also like to use the (sorry for the bad discription but…) the spinny wheely-bob on the base of the joystick for rotation. Thanks for the help.

The spinny wheely-bob is the Axis 3. Holonomic Drive is the drive to use for mecanum.
Good luck.

haha, sorry for the description, I read several posts about using the holonomic drive for mecanum wheels, but this is only my second year of programming so I’m not up on all the lingo. Is there a simpler explination of how to program mecanum wheels, possibly with pictures?

we have a method in java we could give to you if you want

It’s easier to do in Java or C++, but here’s a short demo for LabVIEW. I haven’t tested this out yet, but it should theoretically work:

Assuming you are using two KOP joysticks:

If your drivers like tank drive, we implemented tank-like solution for our crab-drive last year. Basically, we used both Y-axis as a Tank Drive, then used the average X axis to determine the translation angle. When translating at more than 45 degrees, it would turn the front/back pairs into tank drive (instead of the right/left pairs). It worked really well, since our drivers had been trained on tank drive and liked it very much. To implement this, you would use Mecanum-Polar with the Direction as the average of the X-axis multiplied by 90 (to turn the -1/1 into -90/90), Magnitide as the average of the Y-axis, and the Rotation as the difference in X-axis over two.

I would recommend against the “wheelie-bob” since it is not designed to be set while driving, and would be hard for your driver to adjust on-the-fly. Also, you should be aware that it has a range of 0 to 1, not -1,1.

Another thing you could do, you could use the atan2 of left js for a translation angle and the right stick as an arcade drive, that seemed to work well for us in testing. To implement this in LabVIEW, you could use Mecanum-Polar with the Magnaitude being the Y-axis of the right stick, Rotation being the X axis of the right stick, and Direction being atan2 (in degrees) of the left stick.

It all depends on what your driver wants…

@patrick - It is not the language but your understanding of the language that makes things easy or hard. Some people prefer LabVIEW and find things very easy to use, others like C++ or Java.

I set up the program just as you show it here, but when I send it to our robot only two of the motors move. The jaguars for the other motors do not even change color, so why is the code not getting to them? What do you suggest?

How are you opening them in Begin.vi? There should be 4 motors open, and they should be on the correct ports. What color are the status lights on the Jaguars? Blinking yellow, or Solid yellow?

Sorry about that last post, one of our team members accidentally plugged the pwm’s in backwards. The robot can now drive forward backward and rotate within its own foot print. Was the program supposed to make it able to strafe however?

The one Patrick posted a picture of was supposed to strafe, by moving the joystick side-side.

It rotates within its footprint when I move the joystick side to side instead of strafing. Is it possible that our wheels aren’t configured correctly? They are in the x format when viewing them from above.

That sounds like the right wheel orientation…but why do so many people insist on describing the part of the wheel that isn’t actually acting on the ground?

Maybe you don’t have all the PWM connections going to the same wheels you’ve defined in the Open 4 Motor Drive? Put the robot up on blocks and make sure the wheels are moving appropriately. When driving forward, all wheels should run forward. When driving backward, all wheels should run backward. When rotating, the left wheels should run in one direction and the right wheels should run in the other. When driving sideways, the front and back wheels on each side should run opposite from each other.

If all the wheels do what they’re supposed to be doing, you probably just have a weight and balance issue that’s making some wheels run slower than the others with the same values being sent to the speed controllers.

The wheels move as they should other than the fact that they do not perform the strafe action, when i move the joystick side to side nothing happens.

Your descriptions of the problem aren’t consistent. I can’t help you any further without seeing what’s really going on. Sorry.

We haven’t been able to get the strafe motion to work yet. It drives similar to an acrade style driving system, but shouldn’t it strafe as well when using the second joystick?

We’ve never used java before, but if you’re willing to help us out I’d be glad to give it a try.

we used this code for strafing and moving, turning is its own can of worms.

``````public class WesleyCrusher {
private Victor FRvictor = new Victor(2);  //right motor
private Victor FLvictor = new Victor(1);   //left motor
private Victor RRvictor = new Victor(4);  //right motor
private Victor RLvictor = new Victor(3);   //left motor
private Jaguar ballSucker = new Jaguar(7); //ball sucker

boolean DEBUG = true;

void checkingDrive(double magnitude, double rotation) { //DONT TOUCH THIS
magnitude = limit(magnitude);  //1 is highest, so make n > 1, 1
rotation  = limit(rotation);

double frontLeftSpeed, rearLeftSpeed, frontRightSpeed, rearRightSpeed;  //temporary motor speed values

frontLeftSpeed = ((magnitude - rotation));  //calculate speed values
frontRightSpeed = ((magnitude + rotation));
rearLeftSpeed = ((magnitude + rotation));
rearRightSpeed = ((magnitude - rotation));

if(DEBUG) {
double maxMotor = Math.max(
Math.max(Math.abs(frontLeftSpeed), Math.abs(frontRightSpeed)),
Math.max(Math.abs(rearLeftSpeed), Math.abs(rearRightSpeed))
);

if (maxMotor > 1){
frontRightSpeed = frontRightSpeed / maxMotor;
rearRightSpeed = rearRightSpeed / maxMotor;
frontLeftSpeed = frontLeftSpeed / maxMotor;
rearLeftSpeed = rearLeftSpeed / maxMotor;
}
}

frontLeftSpeed = limit(fiddleWithSpeed(frontLeftSpeed));
frontRightSpeed = limit(fiddleWithSpeed(frontRightSpeed));
rearLeftSpeed = limit(fiddleWithSpeed(rearLeftSpeed));
rearRightSpeed = limit(fiddleWithSpeed(rearRightSpeed));

if(magnitude != 0 || rotation !=0) {
System.out.println("#############################################");
System.out.println("Mangnitude: " + magnitude + "  Rotation: " + rotation);  //debugOut
System.out.println("FLSpeed: " + frontLeftSpeed + "  FRSpeed: " + frontRightSpeed);
System.out.println("RLSpeed: " + rearLeftSpeed + "  RRSpeed: " + rearRightSpeed);
}

FLvictor.set(-frontLeftSpeed);  //set the speeds on the motors
FRvictor.set(frontRightSpeed);
RLvictor.set(-rearLeftSpeed);
RRvictor.set(rearRightSpeed);
} //void checkingDrive

void turn(double power) {
if(Math.abs(power) > 0) {
RRvictor.set(power);
RLvictor.set(power);
}
}

double limit(double num) {
if (num > 1.0) {
return 1.0;
}
if (num < -1.0) {
return -1.0;
}
return num;
}
void ballSuckerOn() {
ballSucker.set(0.75);
}

void ballSuckerOff() {
ballSucker.set(0);
}
}

``````

Yes, i name all my code classes after bridge crew of the Enterprise-D