# omni directional motion

i want to design our robot to be able to move in all four directions without turning, but i dont know how the controller would work. what the drivers on my team want is for the right joystick on the controller to control the movement without turning a.k.a push it left it goes left, push it diagonal it goes diagonal. but they want the left joystick to control pivotal turning since we are not going to design a pickup mechanism on every side. so in the end i dont know how to make the controller joysticks control the motors in two compleatly different ways, or if there even is a way. i would figure i have to use strategically placed jumper clips or something but i dont know exactly how those work so can i get an explanation. please help and if you do so thank you.

If you have a robot with 4 omni wheels mounted 90 degrees from each other, then do a search on Holonomic drive code in the forum. Smartkid (Cody) wrote the ultimate in Holonomic drive code and posted it. It does exactly what you want.

If you have the new Mecanum wheel then both RobotC and EasyC have sample code that works with them.

Good luck!

Is this what you are trying to do? Relative mecanum control - YouTube

This isn’t mine, I just found it while searching the web. Sorry I can’t tell you how to do it, but I love the concept.

If I understand what you posted correctly it sounds like you would like the robot to move in the direction of the joystick input regardless of its orientation on the field? While this is doable it requires some fairly serious sensor use and math to go along with sensors to implement this style of control. Personally I don’t believe I’ve talked to anybody who has implemented this kind of control style in Vex.

There are two parts to this type of control. The first changes the x-y (rectangular) coordinate system of the joystick into polar coordinates and then figures out the power for each wheel in a holonomic drive system (either using omni wheels or mecanums). The second (optional) part rotates the coordinate system based on feedback from a gyro so that “forwards” is always the same direction relative to the drivers point of view. You can see the gyro on robot in the demo video.

[ATTACH]6820[/ATTACH]

I’m sure that somewhere on the forum this type of code has been posted before but, having just received the parts necessary to implement this, I will also post an implementation sometime in the next couple of weeks.

1 Like

The holonomic code also works with mecanum drive, as the principles behind that drive are almost identical to those of X Drive.

What’s the difference?

The rollers spinning and not spinning make the math or principal behind it different but the most basic explanation of mecanum and x drive have the same principal.
Canceling vectors to result in only the vectors in the direction you want.

Oh woops… i read the quote wrong. I thought he was refering to code not the mechanics

I am Not a Physics or Mechanical Engineer, but I concur…

With the Gyro Scope module, it might be possible to use the Starting position as the Initial Orientation, and make all Joystick movements relative to that starting position.

On a side note, how well do encoders work on Mecanum wheels? how would you incorporate strafing motion?

I was actually thinking of something like this a while ago, but my team decided it would probably be hard to get used to and it wasn’t really worth it.

There’s a paper on Chief Delphi entitled

“Mecanum & omni with gyro for field-centric control”

It looks a whole lot easier than I though it was going to be.

Also, several other papers on the same subject here

http://www.chiefdelphi.com/media/papers/2390

1 Like

I did a very quick implementation in ROBOTC of the code from the referenced paper in my previous post. I’m not going to post the whole program here as it contains several other “work in progress” libraries but the drive code ended up as follows.

``````task
DriveSystem()
{
int drive_l_front;
int drive_l_back;
int drive_r_front;
int drive_r_back;

int forward, right, clockwise;
int temp;
float theta;

while(true)
{
// Get joystick values
// deadband near center of joysticks
forward = vexRT Ch3 ];
if( abs( forward ) < 10 )
forward = 0;

right = vexRT Ch4 ];
if( abs( right ) < 10 )
right = 0;

clockwise = vexRT Ch1 ];
if( abs( clockwise ) < 10 )
clockwise = 0;

// Get gyro angle in radians

// rotate coordinate system - gyro positive angle is CCW
temp  = forward * cos(theta) - right * sin(theta);
right = forward * sin(theta) + right * cos(theta);
forward = temp;

// Set drive
drive_l_front = forward + clockwise + right;
drive_l_back  = forward + clockwise - right;
drive_r_back  = forward - clockwise + right;
drive_r_front = forward - clockwise - right;

// normalize drive so max is 127 if any drive is over 127
int max = abs(drive_l_front);
if (abs(drive_l_back)  > max)
max = abs(drive_l_back);
if (abs(drive_r_back)  > max)
max = abs(drive_r_back);
if (abs(drive_r_front) > max)
max = abs(drive_r_front);

if (max>127) {
drive_l_front = 127 * drive_l_front / max;
drive_l_back  = 127 * drive_l_back  / max;
drive_r_back  = 127 * drive_r_back  / max;
drive_r_front = 127 * drive_r_front / max;
}

// Send to motors
// left drive
SetMotor( MotorLF, drive_l_front);
SetMotor( MotorLB, drive_l_back);

// right drive
SetMotor( MotorRF, drive_r_front);
SetMotor( MotorRB, drive_r_back);

wait1Msec( 25 );
}
}``````

It’s not very useful out of context, there are other tasks running handling the gyro and motor control but it gives an idea of how the code would be. It actually works really well.

1 Like

We did this. Here’s a paper. Tried to keep it simple, maybe didn’t succeed at that goal. But it should be, more or less, a self contained boot strap to understanding the math. Just make sure to watch the khan academy links in the references.