Our team decided to use mecanum wheels this year and we’ve used java last year. I’m a bit familiar with java but I can’t seem to find a way to approach programming mecanum. I checked out the library but I can’t seem to understand. Does anyone have a simple or pseudo program for mecanum they can share?
Could you articulate in a bit more detail what you don’t understand about the library support for mecanum? You’ll get better-targeted answers if you do that.
Under public class RobotMain extends IterativeRobot,
RobotDrive m_drive;
Under public void RobotInit
m_drive = new RobotDrive(m_frontLeft, m_rearLeft, m_frontRight, m_rearRight); // those reference the motors declared in another section of the code
Under public void TeleoperatedPeriodic
m_drive.mecanumDrive_Cartesian(-1 * m_rstick.getX(),-1 * m_rstick.getY(), -1 * m_lstick.getX(), 0); //m_rstick and m_lstick are just joysticks
That’s the code we’re using right now. Cartesian is much simpler than Polar, because then you don’t have to deal with the annoying trigonometry with polar coordinates. m_rstick and m_lstick are just joysticks. So, based on what we get for input from our joysticks, we can control forward/backward, strafe left/right, and turn clock/counter-clockwise. The rest of the code has been done by the WPI. Sorry if this doesn’t help.
You **COULD **do this:
/* Simulated tank drive controls for mecanum wheels */
magnitude = (leftStick.getMagnitude() + rightStick.getMagnitude()) / 2;
direction = (leftStick.getDirectionDegrees()+rightStick.getDirectionDegrees()) / 2;
rotation = (leftStick.getY() + rightStick.getY()) / 2;
driveRobot.mecanumDrive_Polar(magnitude, direction, rotation);
^ We did it like this because our driver specifically asked for these controls. He has driven tank drive for two years, and I guess old habits are hard to change.
You **SHOULD **do this:
magnitude = leftStick.getMagnitude();
direction = leftStick.getDirectionDegrees();
rotation = rightStick.getX();
driveRobot.mecanumDrive_Polar(magnitude, direction, rotation);
^ This is what we call the FPS drive system (aka. xbox controller style). Left joystick controls w,a,s,d (forward, back, left, right) and diagonal movements. Right joystick controls rotation.
I have the same question, execpt for Labview. i can’t figure how to put the motors in the Begin.vi and how to incoorpoate it into Telop. This is my first time changing our robot to mecanum
Our team is simply using arcade drive, since we’ve been having trouble with both the Polar and Cartesian driving. We have a toggle button that inverts the motors to strafe.
@General25:
You’d probably get better answers in the Labview section, since this is Java.
@General25:
You’d probably get better answers in the Labview section, since this is Java.
sorry, just searched for mecanum and programing
I’ve had a little problem programming the mecanum wheels myself. In my post before I said I had inverted the motors to strafe. Well, turns out that makes a nasty ugly strafe. Anyone have tips regarding how to actually program a strafe with arcade drive?
Thanks.
here’s our current code:
if(joystickL.getTrigger() && state == 0) {
robotDrive.setInvertedMotor(frontLEFT, true);
robotDrive.setInvertedMotor(rearRIGHT, true);
// robotDrive.setInvertedMotor(frontRIGHT, false);
// robotDrive.setInvertedMotor(rearLEFT, false);
this.state = 1;
} else if(joystickL.getTrigger() && state == 1) {
robotDrive.setInvertedMotor(frontLEFT, false);
robotDrive.setInvertedMotor(rearRIGHT, false);
// robotDrive.setInvertedMotor(frontRIGHT, false);
// robotDrive.setInvertedMotor(rearLEFT, false);
this.state = 0;
}
Yes. There’s an explanation here.
**
Thanks for the link. I’m still a little confused here, though.
Could you please explain how I’m supposed to use forward/backward/clockwise in the drive train programming?
That is explained on the second page:
front_left = forward + clockwise + right;
front_right = forward - clockwise - right;
rear_left = forward + clockwise - right;
rear_right = forward - clockwise + right;
// Finally, normalize the wheel speed commands
// so that no wheel speed command exceeds magnitude of 1:
max = abs(front_left);
if (abs(front_right)>max) max = abs(front_right);
if (abs(rear_left)>max) max = abs(rear_left);
if (abs(rear_right)>max) max = abs(rear_right);
if (max>1)
{front_left/=max; front_right/=max; rear_left/=max; rear_right/=max;}
// You're done. Send these four wheel commands to their respective wheels
front_left, front_right, rear_left, rear_right are the commands to send to each mecanum wheel.
If that’s not what you were asking, please clarify your question and I’ll try again.
**
Okay, thanks again. So I just send those wheels in the drive train like so:
RobotDrive driveTrain = new RobotDrive(front_left, rear_left, front_right, rear_right);
Then invert the motors like I’ve been doing, or…?
Without knowing how you have your motors wired I cannot tell you whether or not you need to invert them.
I can tell you this: If your motors are wired so that when you give them a +1 command they go in the “forward” direction, then no inverting is required.
I recommend that you put the robot up on blocks and push the joystick(s) straight forward. If all four wheels spin in the “forward” direction, you’re good to go. If not, then invert any motor that is spinning backwards.
**
No, RobotDrive takes SpeedControllers in its constructor, not actual values. The example was giving you numbers to pass directly to your Jaguars. The sum total of the algorithm and motor control make your own robot drive method, you don’t need the wpilibj version.
Sorry for the late reply.
So far this is what I currently have done and understand well.
import edu.wpi.first.wpilibj.SimpleRobot;
import edu.wpi.first.wpilibj.Compressor;
import edu.wpi.first.wpilibj.GenericHID;
import edu.wpi.first.wpilibj.Gyro;
import edu.wpi.first.wpilibj.Victor;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.Jaguar;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.Joystick;
//Program
public class RobotTemplate extends SimpleRobot {
//Drive Program
RobotDrive drive = new RobotDrive(1, 3, 2, 4);
//Joystick
private Joystick leftStick = new Joystick(1);
//private Joystick rightStick = new Joystick(2);
//Autonomous Program
public void autonomous() {
}
//Teleop
public void operatorControl() {
getWatchdog().setEnabled(true);
//WatchDog Enabled //Infinite Loop
while (isEnabled() && isOperatorControl()) {
getWatchdog().feed();
drive.mecanumDrive_Polar(leftStick.getDirectionDegrees(), leftStick.getMagnitude(), leftStick.getTwist());
Timer.delay(0.005);
}
}
}
I haven’t tested it yet but will tomorrow.
Once I figure out how Cartisian works, I’ll update the code.
Now to figure out the gyro and encoder.
Cartesian/Polar will only work if your wheels are similar to
/
/\
or
/
/
I’m not sure in which order though. Our team made the mistake of putting our mecanum wheels straight on all four sides so that’s something we had to program around.
@Esther:
I managed to get the drive train programmed with your help. Thanks so much!
edit my bad, I mean Ether.
The wheels are supposed to be “straight”, i.e. the plane of all 4 wheels should be parallel to each other.
The rollers on each wheel are at a 45 degree angle to the plane of the wheel, and should form a visual pattern that looks like this when viewed from the top:
*
*
\...../
.....
.....
.....
/.....\
… or this when viewed from the bottom:
*
*
/.....\
.....
.....
.....
\...../
**
Oh, alright. I guess I must’ve misunderstood some posts around here. Thanks for clearing that up.