VEX V5 PYTHON | 01.6 DRIVER CONTROLS
Guide objective
Read left-stick forward/back and right-stick turning input, combine them into left/right motor outputs and test a competition driver loop with deadband and a speed limit.
01 | THE CONTROL SCHEME
Use the left joystick vertically to move forward or backwards. Use the right joystick horizontally to turn. This is a split-stick arcade control scheme: one input sets forward motion and the other sets turning.
Continue with verified motor directions and the competition structure from 01.5. This guide now adds movement during enabled driver control.
| Input | VEX axis | Purpose |
|---|---|---|
| Left stick up/down | axis3 | Forward/back |
| Right stick left/right | axis1 | Turning |
| Right stick up/down | axis2 | Unused here |
| Left stick left/right | axis4 | Unused here |
02 | READ INPUT BEFORE MOVING
Joystick position values range from −100 to +100, with about zero at the centre. Positive axis3 is the forward input; positive axis1 is the right-turn input for this control scheme.
forward = controller.axis3.position() turn = controller.axis1.position()
Confirm these inputs and your wheel directions with the robot supported before floor testing. A motor reversal setting should make positive side commands agree with robot-forward.
03 | MIX FORWARD AND TURN
Add turning to the left side and subtract it from the right. A positive turn increases left-side motion relative to the right, producing a right turn on the standard differential-drive layout.
left = forward + turn right = forward - turn
| Forward | Turn | Raw left | Raw right | Expected action |
|---|---|---|---|---|
| 50 | 0 | 50 | 50 | Forward |
| −50 | 0 | −50 | −50 | Reverse |
| 0 | 30 | 30 | −30 | Right spin |
| 0 | −30 | −30 | 30 | Left spin |
| 50 | 20 | 70 | 30 | Forward curve right |
When reversing, this scheme still treats the right-stick direction as the robot’s yaw direction. Practise reversing curves rather than assuming the controls feel identical to steering a car.
04 | KEEP THE OUTPUTS IN RANGE
Adding inputs can produce values outside ±100. For example, forward 80 plus turn 60 produces left 140 and right 20.
Scale both sides by the same factor when either exceeds the allowed range. Dividing by 1.4 gives approximately left 100 and right 14.29, preserving the relative mix.
The supplied code then scales both outputs by a 30% test limit. This limits command percentage, not guaranteed ground speed. Cartridges, external gearing and load still affect motion.
05 | DEADBAND AND TURNING GAIN
A centred joystick can return small non-zero values. A deadband treats inputs within a small range around zero as zero. The example uses ±5.
Turning gain scales the turning input. The example uses 0.7 so turning is less aggressive than full unscaled input. Change one setting at a time and ask the driver to compare results.
This is simple proportional control. It does not include acceleration ramping, curved joystick response or heading correction. Those can be added after the basic controls are reliable.
06 | TRY THE MIX WITHOUT A ROBOT
Move the sliders to predict the motor outputs. This preview uses the same deadband, 0.7 turning gain, normalisation and 30% limit as the starter code.
07 | COMPLETE FOUR-MOTOR DRIVER STARTER
Place this below # Begin project code, keeping the generated VEX import and Brain setup above it. Replace earlier user-code starters instead of leaving duplicate functions or registration.
Do not configure the same motors or Controller twice. This example declares them manually; remove conflicting Devices-panel entries. Also remove any automatic Devices-panel driving assignment so it does not compete with this driver loop.
Verify ports, cartridges and reversal flags. The initial 30% limit is deliberate. Support the robot with its wheels clear of the floor for the first direction and centred-stick tests.
# =============================================================================
# TEAM [MY TEAM NAME / NUMBER]
# =============================================================================
# ROBOT CONFIGURATION
# - FOUR-motor drivetrain:
# Left = Ports 3 and 4
# Right = Ports 1 and 2
# - Example: blue cartridges, left normal, right reversed.
# VERIFY your actual ports, cartridges and direction settings.
# DRIVER CONTROLS
# - Left joystick vertical (axis3): forward/back
# - Right joystick horizontal (axis1): turn
# - This program MOVES motors in enabled driver-control mode.
# - Add BELOW # Begin project code, outside generated configuration.
# - Do not also define these drive motors in the Devices panel.
# - Keep generated from vex import * and brain = Brain() above.
# =============================================================================
# FOUR-MOTOR DRIVETRAIN
# =============================================================================
left_motor_1 = Motor(Ports.PORT3, GearSetting.RATIO_6_1, False)
left_motor_2 = Motor(Ports.PORT4, GearSetting.RATIO_6_1, False)
right_motor_1 = Motor(Ports.PORT1, GearSetting.RATIO_6_1, True)
right_motor_2 = Motor(Ports.PORT2, GearSetting.RATIO_6_1, True)
left_drive = MotorGroup(left_motor_1, left_motor_2)
right_drive = MotorGroup(right_motor_1, right_motor_2)
# =============================================================================
# CONTROLLER, SETTINGS AND HELPERS
# =============================================================================
controller = Controller(PRIMARY) # Do not duplicate a generated Controller
DEADBAND = 5
DRIVE_LIMIT_PERCENT = 30 # Start low; increase only after testing
TURN_GAIN = 0.7
LOOP_DELAY_MS = 20
def apply_deadband(value):
return 0 if abs(value) <= DEADBAND else value
def drive_mix(forward, turn):
left = forward + turn
right = forward - turn
largest = max(100, abs(left), abs(right))
left = left * 100 / largest
right = right * 100 / largest
return (left * DRIVE_LIMIT_PERCENT / 100,
right * DRIVE_LIMIT_PERCENT / 100)
def set_side_output(side, output):
if abs(output) < 0.01:
side.stop(BRAKE)
elif output > 0:
side.spin(FORWARD, output, PERCENT)
else:
side.spin(REVERSE, -output, PERCENT)
def show_status(message):
brain.screen.clear_screen()
brain.screen.set_cursor(1, 1)
brain.screen.print(message)
def stop_drive():
left_drive.stop(BRAKE)
right_drive.stop(BRAKE)
# =============================================================================
# PRE-AUTON: CALLED ONCE AT PROJECT STARTUP
# =============================================================================
def pre_autonomous():
stop_drive()
show_status("Setup ready")
# Later: initialise sensors and starting values here.
# Finish setup before the robot is enabled for a match.
# =============================================================================
# AUTONOMOUS: A FINITE ROUTINE
# =============================================================================
def autonomous():
show_status("Autonomous")
# Later: add your tested autonomous action sequence here.
# No autonomous movement in this starter.
stop_drive()
# =============================================================================
# DRIVER CONTROL: REPEATING UPDATES WHILE ENABLED
# =============================================================================
def driver_control():
show_status("Driver control")
while competition.is_enabled() and competition.is_driver_control():
forward = apply_deadband(controller.axis3.position())
turn = apply_deadband(controller.axis1.position()) * TURN_GAIN
left_output, right_output = drive_mix(forward, turn)
set_side_output(left_drive, left_output)
set_side_output(right_drive, right_output)
wait(LOOP_DELAY_MS, MSEC)
stop_drive()
# =============================================================================
# PROGRAM START: SETUP, THEN CALLBACK REGISTRATION
# =============================================================================
pre_autonomous()
competition = Competition(driver_control, autonomous)
# Keep the main task alive without running a driving loop here.
while True:
wait(100, MSEC)
Negative mixed outputs are converted into REVERSE commands with a positive speed magnitude. Zero output explicitly stops that side using BRAKE. The loop runs only while enabled in driver-control mode and waits 20 ms between updates.
For a two- or six-motor drivetrain, substitute your verified declarations from 01.3 while keeping left_drive and right_drive. Autonomous remains a stop-only placeholder.
08 | TEST ONE ACTION AT A TIME
- Pair and connect the Controller to the Brain using the normal VEX setup.
- Download the correct project and select driver-control mode using your competition-testing setup.
- Leave both sticks centred: all drive outputs should stop.
- Move only the left stick forward, then backwards.
- Centre it and move only the right stick right, then left.
- Combine gentle forward input with turning input.
- Disable and confirm motion stops before moving to a clear floor test.
Verify behaviour when the Controller link is interrupted as part of a supervised test; do not assume a screen message proves the connection is healthy. Keep a way to stop the robot throughout testing.
09 | TROUBLESHOOT THE CAUSE
- Forward makes the robot spin: check motor reversal and side membership.
- Wrong stick controls motion: inspect axis3 and axis1 reads.
- Robot creeps at centre: inspect raw inputs and adjust deadband modestly.
- Turning feels too sharp: reduce TURN_GAIN before changing several settings.
- Unexpected commands compete: check for automatic Controller assignments or another driving thread.
- Nothing moves: confirm pairing, program slot, enabled driver mode and successful download.
CHALLENGES | BUILD DRIVER CONFIDENCE
- Explain the axes: show a partner which stick motion is axis3 and which is axis1.
- Predict the mix: calculate outputs for straight motion, a spin and a forward curve, then compare with the preview.
- Verify the basics: record supported-wheel results for centred sticks, forward, reverse, left and right.
- Tune one value: compare turning gains of 0.5 and 0.7 at the same drive limit.
- Drive a route: in a clear area, follow a slow rectangle and practise controlled reversing.
- Test transitions: confirm disable and re-enable behaviour with the competition setup.
- Document preferences: record deadband, speed limit and turning gain in your team’s settings section.
Success evidence
A saved project, correct left/right-stick control, no centred-stick creep, verified stopping on disable and a short driver feedback log.
OFFICIAL REFERENCE
VEX V5 Python Controller API and joystick axes
This is an independent learning resource; VEX and VEXcode are trademarks of their respective owners.