So I’m fairly competent in vexcode (meaning I can read and understand stuff others give to me) but am not sure how to make a program to control strafing with mecanum wheels. I want tank driving with strafing on the left joystick. Anyone have examples?
So you want to make it feel as if it’s a normal tank drive, but have the horizontal axis dedicated to strafing?
Do you already know how to program a tank drive with VEXCode? If so, this should be pretty simple.
The axes 1 and 4 are for horizontal values (1 on the right, 4 on the left). To program the ability to strafe, you would program one of these axes the same way you program 2 or 3. The only differences are that one stick controls all 4 wheels, and that the front 2 must spin the opposite direction of the back 2.
When programming a drive the general ideas is to add up all the values for the wheels, this may incude forward, sideways, left, right and/or turn. This picture shows the direction each wheel should go for mecanum wheels…
Using this your code should look something like this…
int forward = /*your value*/;
int sideways = /*your value*/;
int turn = /*your value*/;
frontRight.spin(vex::forward, forward - sideways + turn, vex::percent);
frontLeft.spin(vex::forward, forward + sideways - turn, vex::percent);
backRight.spin(vex::forward, forward + sideways + turn, vex::percent);
backLeft.spin(vex::forward, forward - sideways - turn, vex::percent);
Also note that the reason you add up the values is to allow the robot to do multiple of these actions at once. Meaning it can drive diagonally by setting forwards and sideways to some values.
Next for driver control the three variables need to be set by the joystick values. You said that…
Whilst certainly possible, this type of control probably would not work very well for the drivers. With tank drive it is hard to keep the joysticks at exactly zero horizontally, so the robot would always be moving sideways a little while driving, which could be annoying. Most use an arcade drive. This places forward and sideways movement on one joystick and turning on the other.
Still feel free to try both ways…
How you asked
int left = Controller.Axis3.position(vex::percent);
int right = Controller.Axis2.position(vex::percent);
int sideways = Controller.Axis4.position(vex::percent);
//you can also calculate this...
int turn = (right - left) * 0.5;
int forward = (right + left) * 0.5;
frontRight.spin(vex::forward, right - sideways, vex::percent);
frontLeft.spin(vex::forward, left + sideways, vex::percent);
backRight.spin(vex::forward, right + sideways, vex::percent);
backLeft.spin(vex::forward, left - sideways, vex::percent);
Arcade Drive
int forward = Controller.Axis3.position(vex::percent);
int sideways = Controller.Axis4.position(vex::percent);
int turn = Controller.Axis1.position(vex::percent);
frontRight.spin(vex::forward, forward - sideways + turn, vex::percent);
frontLeft.spin(vex::forward, forward + sideways - turn, vex::percent);
backRight.spin(vex::forward, forward + sideways + turn, vex::percent);
backLeft.spin(vex::forward, forward - sideways - turn, vex::percent);
Thanks, this was the answer I needed. I am the driver and have driven tank strafing before and liked it and I dislike arcade, so unless I find that it’s hard to use I’ll probably use tank. Those addition and subtraction formulas were what I needed, thanks.
This is what we did to get mecanum drive to work.
robot-config.cpp
#include “vex.h”
using namespace vex;
using signature = vision::signature;
using code = vision::code;
// A global instance of brain used for printing to the V5 Brain screen
brain Brain;
// VEXcode device constructors
controller Controller1 = controller(primary);
motor frontRight = motor(PORT1, ratio18_1, true);
motor backRight = motor(PORT2, ratio18_1, true);
motor frontLeft = motor(PORT9, ratio18_1, false);
motor backLeft = motor(PORT10, ratio18_1, false);
motor lift = motor(PORT5, ratio18_1, false);
motor dump = motor(PORT6, ratio18_1, false);
// VEXcode generated functions
// define variable for remote controller enable/disable
bool RemoteControlCodeEnabled = true;
/**
- Used to initialize code/tasks/devices added using tools in VEXcode Text.
- This should be called at the start of your int main function.
*/
void vexcodeInit( void ) {
// nothing to initialize
}
main.cpp
/----------------------------------------------------------------------------/
/* /
/ Module: main.cpp /
/ Author: E. Leet /
/ Created: Tue Mar 10 2020 /
/ Description: V5 project /
/ /
/----------------------------------------------------------------------------*/
// ---- START VEXCODE CONFIGURED DEVICES ----
// Robot Configuration:
// [Name] [Type] [Port(s)]
// Controller1 controller
// frontRight motor 1
// backRight motor 2
// frontLeft motor 9
// backLeft motor 10
// lift motor 5
// dump motor 6
// ---- END VEXCODE CONFIGURED DEVICES ----
#include “vex.h”
using namespace vex;
int main() {
// Initializing Robot Configuration. DO NOT REMOVE!
vexcodeInit();
while (true) {
// Axis 3 drives forward and backward
int forward = Controller1.Axis3.position(vex::percent);
// Axis 4 turns left and right
// My left and right were reverse, so I had to add
// 0 - to make the turn variable opposite value
int turn = 0 - Controller1.Axis4.position(vex::percent);
// Strife or mecanum drive is on Axis 1
// Sideways is axis 1
int sideways = Controller1.Axis1.position(vex::percent);
frontRight.spin(vex::forward, forward - sideways + turn, vex::percent);
frontLeft.spin(vex::forward, forward + sideways - turn, vex::percent);
backRight.spin(vex::forward, forward + sideways + turn, vex::percent);
backLeft.spin(vex::forward, forward - sideways - turn, vex::percent);
// Runs motor off the L1 and L2 Buttons
if( Controller1.ButtonL1.pressing() )
{
lift.spin(vex::forward, 50, vex::percent);
}
else if(Controller1.ButtonL2.pressing())
{
lift.spin(vex::reverse, 50, vex::percent);
}
else
{
lift.stop();
}
// Runs motor off the R1 and R2 Buttons
if( Controller1.ButtonR1.pressing() )
{
dump.spin(vex::forward, 50, vex::percent);
}
else if(Controller1.ButtonR2.pressing())
{
dump.spin(vex::reverse, 50, vex::percent);
}
else
{
dump.stop();
}
}
}