My students have built a small x-drive drivetrain and want to code it. Can anyone point me in the right direction for a set of instructions I can give them on graphical robotc code that will operate the holonomic drivetrain properly?

The VEX video tutorial by Cody is way beyond their understanding.

I think it’s pretty clunky to do in graphical because as far as I can see, there is no way to sum three bits of data in a single line.

Basically you want to say

Loop forever{

setMotor(frontRight, getJoystickValue(ChD) - getJoystickValue(ChB) - getJoystickValue(ChC);

setMotor(backRight, getJoystickValue(ChD) - getJoystickValue(ChB) + getJoystickValue(ChC);

setMotor(frontLeft, getJoystickValue(ChD) + getJoystickValue(ChB) + getJoystickValue(ChC);

setMotor(backLeft, getJoystickValue(ChD) + getJoystickValue(ChB) - getJoystickValue(ChC);

}

But I can’t see an easy way to do it, something like this might work (untested!)

Thanks! The text version works, but if I want my students to be able to add anything they’ll need to either learn text or try your block version. Can you explain what’s going on there?

It really depends on what kind of controls you’re trying to achieve.

For X-drive, I have seen a wide gamut of possible control complexities.

The easiest is to map tank control + strafing - you define what is the robot front, then you have 2 motors on the left (and declared as such in the motor setup) and 2 motors on the right (with proper reversals). Your code would use two buttons for strafing (sideway movement), so the overall structure would be like:

```
if (leftButton) {
setMotor(FL, -50);
setMotor(FR, 50);
setMotor(RL, 50);
setMotor(RR, -50);
} else if (rightButton) {
setMotor(FL, 50);
setMotor(FR, -50);
setMotor(RL, -50);
setMotor(RR, 50);
} else {
tankControl(ChD, ChA, 20);
}
```

This is easy to do in graphical and also easiest to explain.

The code posted by @calvc01 is akin to Arcade control with proportional strafing control. The idea is that one joystick axis (ChD) would control the robot’s front/back movement, other (ChC) would turn (so pretty much arcade on the right thumb), while the other stick would allow going sideways - but unlike the first case, all at once so you could go diagonally and even turn at the same time.

If you want to explain this to the students, start by evaluating one joystick channel with others at zero - once they remove the zero terms, it would be clear how that single channel drives the motors. Rinse and repeat for remaining channels.

Most advanced implementation is out of reach of graphical and (sadly) out of reach of most US middle-school math. It would use gyro, trigonometry and a bit of vector math to allow the robot to perfectly follow the direction in which one joystick is pointing (regardless of the actual robot rotation), while other joystick could rotate the robot at the same time.

(I should post a video of a rotating robot following a straight line on the field, it looks soooo satisfying). But the code is surprisingly simple.

Edit: code format

Out of interest, were you able to try my graphical attempt and see if it worked? I’ll post the actual code file when I am at my laptop so you can download it and try it.

How does the text code work? Well basically for each motor, it takes the readings from 3 joystick axis to work out what to do to that motor. The easiest way to understand what it is doing to each motor is write down a few examples on paper and follow it through.

ChD is forwards and backwards

ChB is the rotation

ChC is the strafe

The first thing to remember is that the motors want a value from -100 (full backwards) to +100 (full forwards) with 0 being stop.

The joysticks return the same values from -100 (full left or full down) to +100 (full up or full right) with 0 in the middle.

So, imagine we push ChD full up (+100) but all the other sticks are in the middle (0):

setMotor(frontRight, getJoystickValue(ChD) - getJoystickValue(ChB) - getJoystickValue(ChC); this will be 100 minus 0 minus 0 = 100

setMotor(backRight, getJoystickValue(ChD) - getJoystickValue(ChB) + getJoystickValue(ChC); this will be 100 minus 0 plus 0 = 100

setMotor(frontLeft, getJoystickValue(ChD) + getJoystickValue(ChB) + getJoystickValue(ChC); this will be 100 plus 0 plus 0 = 100

setMotor(backLeft, getJoystickValue(ChD) + getJoystickValue(ChB) - getJoystickValue(ChC); this will be 100 plus 0 minus 0 = 100

So you can see all the motors end up on 100 and so the robot goes forwards. Now lets take a look what happens if you hold the rotate stick (ChB) full left (-100)

It gets a bit complicated because sometimes you are subtracting a negative value - keep your eyes peeled!

setMotor(frontRight, getJoystickValue(ChD) - getJoystickValue(ChB) - getJoystickValue(ChC); this will be 0 minus -100 minus 0 = 100

setMotor(backRight, getJoystickValue(ChD) - getJoystickValue(ChB) + getJoystickValue(ChC); this will be 0 minus -100 plus 0 = 100

setMotor(frontLeft, getJoystickValue(ChD) + getJoystickValue(ChB) + getJoystickValue(ChC); this will be 0 plus -100 plus 0 = -100

setMotor(backLeft, getJoystickValue(ChD) + getJoystickValue(ChB) - getJoystickValue(ChC); this will be 0 plus -100 minus 0 = -100

So now the two right motors go forwards and the two left motors go backwards - the robot rotates left (counter-clockwise)

Now lets see what happens if you hold the strafe stick (ChC) full right (100):

setMotor(frontRight, getJoystickValue(ChD) - getJoystickValue(ChB) - getJoystickValue(ChC); this will be 0 minus 0 minus 100 = -100

setMotor(backRight, getJoystickValue(ChD) - getJoystickValue(ChB) + getJoystickValue(ChC); this will be 0 minus 0 plus 100 = 100

setMotor(frontLeft, getJoystickValue(ChD) + getJoystickValue(ChB) + getJoystickValue(ChC); this will be 0 plus 0 plus 100 = 100

setMotor(backLeft, getJoystickValue(ChD) + getJoystickValue(ChB) - getJoystickValue(ChC); this will be 0 plus 0 minus 100 = -100

So the front right and back left wheels go backwards and the front left and back right go forwards so the robot strafes right.

These are the simplest examples but if you try thinking about some joystick inputs where there are two or more numbers to work with, you can work out what will happen.