Hey guys!
I’ve finally got around to remaking my infamous holonomic drive video tutorial, this time in a Khan Academy styled two part series covering omni wheels, applications of omni wheels, holonomic drives and how to program both the “X” and “+” holonomic drives we’re all come to know and love.
Original thread - Sorry guys, the old thread was removed.
VIDEO TUTORIALS:
VIDEO 1: Omni wheels and holonomic drives
VIDEO 2: How to program holonomic drives
The signs in this drawing are all flipped, this is because I guessed the rotational
direction of the VEX motors wrong. The code below has been corrected.
The following code assumes that you have not reversed the polarity of the two-wire motor(s) AT ANY POINT,
if you have you will need to either configure that motor as reversed or flip all the signs for that motor.
ROBOTC
// Cody's ROBOTC X Holonomic Code
// =======================
// Usage: Drive code for "X" Holonomic drive
// License: Public Domain, use at your own risk.
//
// ROBOT SEEN FROM ABOVE
//
// X FRONT X
// X X
// X P1 P2 X
// X
// XXX
// X
// X P4 P3 X
// X X
// X X
// Controller 1/2, Stick L/R, Axis X/Y
#define C1LX vexRT[Ch4]
#define C1LY vexRT[Ch3]
#define C1RX vexRT[Ch1]
task main() {
while(true) {
// Y component, X component, Rotation
motor[FL] = -C1LY - C1LX - C1RX;
motor[FR] = C1LY - C1LX - C1RX;
motor[BR] = C1LY + C1LX - C1RX;
motor[BL] = -C1LY + C1LX - C1RX;
// Motor values can only be updated every 20ms
wait10Msec(2);
}
}
// Cody's ROBOTC + Holonomic Code
// =======================
// Usage: Drive code for "+" Holonomic drive
// License: Public Domain, use at your own risk.
// Controller 1/2, Stick L/R, Axis X/Y
#define C1LX vexRT[Ch4]
#define C1LY vexRT[Ch3]
#define C1RX vexRT[Ch1]
task main() {
while(true) {
// Y component, X component, Rotation
motor[FR] = -C1LX - C1RX;
motor[LE] = -C1LY - C1RX;
motor[RI] = C1LY - C1RX;
motor[BK] = C1LX - C1RX;
// Motor values can only be updated every 20ms
wait10Msec(2);
}
}
PROS
// Cody's PROS X Holonomic Code
// =======================
// Usage: Drive code for "X" Holonomic drive
// License: Public Domain, use at your own risk.
//
// ROBOT SEEN FROM ABOVE
//
// X FRONT X
// X X
// X P1 P2 X
// X
// XXX
// X
// X P4 P3 X
// X X
// X X
void operatorControl() {
while(1) {
// Controller 1/2, Stick L/R, Axis X/Y
int C1LX = joystickGetAnalog(1, 4);
int C1LY = joystickGetAnalog(1, 3);
int C1RX = joystickGetAnalog(1, 1);
// Y component, X component, Rotation
motorSet(1, -C1LY - C1LX - C1RX);
motorSet(2, C1LY - C1LX - C1RX);
motorSet(3, C1LY + C1LX - C1RX);
motorSet(4, -C1LY + C1LX - C1RX);
// Motor values can only be updated every 20ms
delay(20);
}
}
// Cody's PROS + Holonomic Code
// =======================
// Usage: Drive code for "+" Holonomic drive
// License: Public Domain, use at your own risk.
void operatorControl() {
while(1) {
// Controller 1/2, Stick L/R, Axis X/Y
int C1LX = joystickGetAnalog(1, 4);
int C1LY = joystickGetAnalog(1, 3);
int C1RX = joystickGetAnalog(1, 1);
// Y component, X component, Rotation
motorSet(1, -C1LX - C1RX); // Front
motorSet(2, -C1LY - C1RX); // Left
motorSet(3, C1LY - C1RX); // Right
motorSet(4, C1LX - C1RX); // Back
// Motor values can only be updated every 20ms
delay(20);
}
}
ConVEX
// Cody's ConVEX X Holonomic Code
// =======================
// Usage: Drive code for "X" Holonomic drive
// License: Public Domain, use at your own risk.
//
// ROBOT SEEN FROM ABOVE
//
// X FRONT X
// X X
// X P1 P2 X
// X
// XXX
// X
// X P4 P3 X
// X X
// X X
msg_t vexOperator(void * arg) {
// Register this task
vexTaskRegister("operator");
while(1) {
// Controller 1/2, Stick L/R, Axis X/Y
int C1LX = vexControllerGet(Ch4);
int C1LY = vexControllerGet(Ch3);
int C1RX = vexControllerGet(Ch1);
// Y component, X component, Rotation
vexMotorSet(1, -C1LY - C1LX - C1RX);
vexMotorSet(2, C1LY - C1LX - C1RX);
vexMotorSet(3, C1LY + C1LX - C1RX);
vexMotorSet(4, -C1LY + C1LX - C1RX);
// Exit condition
if(chThdShouldTerminate()) break;
// Motor values can only be updated every 20ms
vexSleep(20);
}
return (msg_t)0;
}
// Cody's ConVEX + Holonomic Code
// =======================
// Usage: Drive code for "+" Holonomic drive
// License: Public Domain, use at your own risk.
msg_t vexOperator(void * arg) {
// Register this task
vexTaskRegister("operator");
while(1) {
// Controller 1/2, Stick L/R, Axis X/Y
int C1LX = vexControllerGet(Ch4);
int C1LY = vexControllerGet(Ch3);
int C1RX = vexControllerGet(Ch1);
// Y component, X component, Rotation
vexMotorSet(1, -C1LX - C1RX); // Front
vexMotorSet(2, -C1LY - C1RX); // Left
vexMotorSet(3, C1LY - C1RX); // Right
vexMotorSet(4, C1LX - C1RX); // Back
// Exit condition
if(chThdShouldTerminate()) break;
// Motor values can only be updated every 20ms
vexSleep(20);
}
return (msg_t)0;
}
This is a bit of an experiment, a new way of doing things, etc. If you like the format please let me know and also let me know what other topics you’d like me to cover.
Questions / comments / concerns / grievances below…
-Cody