Hi, My team is new to using mecanum wheels and we need help with correctly programming them?
This shows in which direction you should power the motors in order to get the indicated net direction.
If you need more help turning this diagram into a code, just ask and we would be glad to assist you further.
I am not the thread-poster, but I would like some help turing this into a good drive code.
I made a tutorial back when the wheels were released: http://www.youtube.com/watch?v=v7CujEW0wgc
From magicode’s (very well-done) tutorial:
FrontLeft = Ch3 + Ch1 + Ch4
RearLeft = Ch3 + Ch1 - Ch4
FrontRight = Ch3 - Ch1 - Ch4
RearRight = Ch3 - Ch1 + Ch4
Ch1 = Right joystick X-axis
Ch3 = Left joystick Y-axis
Ch4 = Left joystick X-axis
Where positive is to the right or up on the joysticks.
There may be strange issues when all three inputs are near their max values, but it shouldn’t be too much of an issue unless your driver has very happy thumbs.
So just taking the above (from magicode’s tutorial) as drive code would work fine.
My diagram was more for seeing how different motor directions interacted to create robot strafing movements. As for coding, just adding together the three inputs as magicode did works fine. You could theoretically use the diagram for mapping inputs to outputs, but that would probably involve using if statements in your mapping, which you probably don’t want to do.
Thanks! This is a big help.
I created something very smilar to this by allocating percentages to each component of movement.
If the left joystick is pushed without the right joystick, I assign a variable turnComponent to be 100% of the left joystick’s channel and strafeComponent to be 0.
If the right joystick is pushed without the left joystick, I assign strafeComponent to be 100% of the right joystick’s channel and turnComponent to be 0.
If both are pressed, I assign turnComponent to be 50% of the left joystick’s channel and stafeComponent to be 50% of the right joystick’s channel.
Then I just add components like you posted.
Thanks for all the great help guys!:)
Don’t you only need the 50% is both joysticks are being used? Because if only one is being used, it doesn’t matter if both are at 100% because the other one is 0 anyways.
Assigning linear values makes for a very simple (but still workable) drive. For a more responsive drive, you’ll probably want an exponential mapping from the joysticks to the wheels with a button for low/high speed mode.
The flexibility of Movement with the Mecanum Wheels reminded me of something…
*For the 2009 USFIRST, FRC competition, I was Mentoring a Team that chose a Crab Drive Mechanism for their Drive Train.
On the programming side, I helped develop a Control System which treats the X and Y of One Joystick as a Direction to turn the Crab Mechanism, achieved by converting from Rectangular Coordinates to Polar Coordinates, the Other Joystick was used for the Speed.*
I could see a similar abstraction used with the Mecanum Wheels, for changing the Direction of Motion, without changing the Orientation of the Robot. Or changing the Orientation, without changing the Direction of Motion.
Plus a few other Movements that could provide interesting…
I’ve worked on a holonomic drive that maintained it’s direction relative to the controller using a gyroscope. It was interesting , but actually harder to drive in my opinion.
One of my teams used this type of drive for Gateway and loved it. They used the left joystick for direction of travel and the right joystick for rotation. Being able to rotate while driving helped with their speed of scoring and there was never any confusion on direction based on which way the “front” of the robot was facing. The maneuverability allowed them to easily defend against faster/stronger robots as well as get around robots attempting to defend against them.
Yep, that’s always a good idea. I usually do something like this:
#define DEADZONE 20 FrontLeft = Ch3 + Ch1 + Ch4; RearLeft = Ch3 + Ch1 - Ch4; FrontRight = Ch3 - Ch1 - Ch4; RearRight = Ch3 - Ch1 + Ch4; motor[frontLeft] = abs(FrontLeft) > DEADZONE ? FrontLeft : 0; motor[rearLeft] = abs(RearLeft) > DEADZONE ? RearLeft : 0; motor[frontRight] = abs(FrontRight) > DEADZONE ? FrontRight : 0; motor[rearRight] = abs(RearRight) > DEADZONE ? RearRight : 0;
I used the deadzone value of 20 here as an example, but the actual value will depend on your gear ratio and configuration.
I’ve found that calibrating the joysticks really helps with the trimming issue. The joysticks still read a value of 1 for some reason, but at least they’re all the same.
What we like doing is:
MotorPower = Joystick + sgn(Joystick) * MINPOWER; MotorPower = ( abs(MotorPower) > DEADZONE ) ? MotorPower : 0;
where MINPOWER is the minimum power that can be supplied to a motor for the robot to move (at its absolute slowest speed, where it is just barely overcoming friction).
Do you use a DEADZONE of 20, like magicode??
That would be ±20 on a Scale of ±127, close to 1/5 of the total range.
We usually use a DEADZONE of about 2 and a MINPOWER of about 20 (depending on the robot, the gear ratio, etc.).
Thank You very much…
I will be experimenting with the Mecanum Wheels this coming week, and I am so glad to benefit from the Experience of those that have already worked with them…
This Thread has some Fantastic Information contained with in it, constituting many Dozens of Hours of Work and Experimentation…
I commend you all!!!
Sorry, I just used 20 as an example number. For a 1:1 mecanum drive, I would personally use a non linear mapping of the joysticks to the wheels, with a deadzone of around 5 - 10.
I’m curious. How would you do a non-linear mapping?
I’ve thought about having the first ( 2 * MINPOWER - DEADZONE ) joystick values use a linear mapping such that two joystick values correspond to each output value. That way, you have more sensitive control when going at lower speeds.
If you’re wondering how I figured the math for the mapping:
I know it’s very simple, but it’s all I’ve got…