VEX V5 PYTHON | 02.4 STOPPING BEHAVIOUR
Guide objective
Compare coast, brake and hold, distinguish a default stopping setting from a stop command and test suitable choices for drivetrains and mechanisms.
01 | A STOP COMMAND IS NOT ONE FIXED BEHAVIOUR
A moving robot has momentum. Removing the driving command, resisting rotation and actively maintaining a position are different actions.
VEX provides three stopping modes: COAST, BRAKE and HOLD. Choose based on what should happen while slowing and after rotation has stopped.
02 | COAST: LET THE MECHANISM SLOW
COAST removes active driving and lets the motor and mechanism slow under friction and load. The wheel can continue rotating after the command.
This can suit a mechanism that should freewheel or a drivetrain where a softer release is desired. It can also increase run-on distance, making a precise stop harder.
Coast does not mean zero friction. Gearboxes, tyres and the load still resist motion. A robot on a slope or a loaded lift may move when released.
03 | BRAKE: RESIST ROTATION
BRAKE applies braking behaviour to oppose rotation and generally stops a moving mechanism more sharply than coasting under comparable conditions.
It does not continuously servo back to the exact stopped angle in the same way as HOLD. It is often a useful starting choice for drivetrain tests.
Do not interpret braking as an instantaneous physical stop. Momentum, traction, gearing and the surface still affect stopping distance. Abrupt deceleration can also cause slipping or tipping on some builds.
04 | HOLD: MAINTAIN MOTOR POSITION
HOLD actively attempts to maintain the motor’s stopped position. It can resist a load that would otherwise move a mechanism, within the motor’s capabilities.
Holding can draw current and produce heat while resisting a load. It cannot overcome unlimited force, repair loose hardware or guarantee that a robot stays fixed on the floor.
A motor holding its shaft angle is different from a robot holding a field coordinate: wheels can slip. Do not rely on powered holding to support a raised mechanism during maintenance, while disabled or after power loss.
05 | COMPARE THE THREE MODES
| Mode | Main effect | After slowing | Example consideration |
|---|---|---|---|
| COAST | Allow natural slowdown | No active position control | Freewheeling or soft release |
| BRAKE | Resist rotation | No continuous position correction like hold | Sharper drivetrain stop |
| HOLD | Stop and maintain motor angle | Active correction while permitted and powered | Mechanism position retention |
There is no universally best setting. A drivetrain, intake and lift may need different stopping behaviour. Test under the actual load and competition state.
06 | DEFAULT SETTING VS EXPLICIT STOP
left_drive.set_stopping(BRAKE) right_drive.set_stopping(BRAKE) # Later: stop using the configured default. left_drive.stop() right_drive.stop() # Or explicitly choose the mode for this stop. left_drive.stop(COAST) right_drive.stop(COAST)
set_stopping configures the behaviour used by later stops; it does not by itself stop a currently moving motor. stop issues the stop action.
drivetrain.set_stopping(BRAKE) drivetrain.drive_for(FORWARD, 300, MM) drivetrain.stop()
If your code controls MotorGroups directly, make its stop commands explicit. Do not assume that a Drivetrain default overrides every direct group stop elsewhere in your project.
07 | CHECK YOUR EXISTING HELPERS
In the driver starter from 01.6, zero output calls side.stop(BRAKE). A new default setting would not change that explicit request. Decide whether centred-stick stopping should use a configurable mode.
DRIVER_STOP_MODE = BRAKE # Inside the zero-output branch: side.stop(DRIVER_STOP_MODE)
Keep this separate from the autonomous experiment’s TEST_STOP_MODE. That way, changing a test condition does not silently change normal driver handling.
Also distinguish stopping mode from acceleration or braking ramps. A ramp gradually changes commanded output; the stopping mode determines the motor’s stop behaviour.
08 | COMPLETE STOPPING COMPARISON PROJECT
The following uses explicit four-motor declarations and the established driver controls. Autonomous runs a short timed forward test, then stops using TEST_STOP_MODE. It leaves an observation interval before releasing to coast.
Run separate trials for each mode. This timed experiment isolates the stop action; it is not a distance-accuracy routine. Record the stopping point and run-on using video or a consistent measurement method.
Keep generated imports and Brain setup above the user code. Paste below # Begin project code, replacing previous starters. Match ports, cartridges and reversal flags, and avoid duplicate Devices entries.
# =============================================================================
# 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 during an autonomous stopping test.
# - Driver control keeps the established split-stick scheme.
# - Repeat separate trials with COAST, BRAKE and HOLD.
# - 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
TEST_STOP_MODE = BRAKE # Change to COAST or HOLD for separate trials
DRIVER_STOP_MODE = BRAKE # Centred-stick behaviour; independent of test
TEST_SPEED_PERCENT = 15
RUN_TIME_MS = 500
OBSERVE_TIME_MS = 1500
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(DRIVER_STOP_MODE)
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(mode=BRAKE):
left_drive.stop(mode)
right_drive.stop(mode)
# =============================================================================
# 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():
if not (competition.is_enabled() and competition.is_autonomous()):
stop_drive()
return
show_status("Stopping comparison")
left_drive.spin(FORWARD, TEST_SPEED_PERCENT, PERCENT)
right_drive.spin(FORWARD, TEST_SPEED_PERCENT, PERCENT)
elapsed_ms = 0
while elapsed_ms < RUN_TIME_MS:
if not (competition.is_enabled() and competition.is_autonomous()):
stop_drive()
return
wait(10, MSEC)
elapsed_ms += 10
stop_drive(TEST_STOP_MODE)
show_status("Observe selected stop mode")
elapsed_ms = 0
while elapsed_ms < OBSERVE_TIME_MS:
if not (competition.is_enabled() and competition.is_autonomous()):
stop_drive()
return
wait(10, MSEC)
elapsed_ms += 10
# Release powered holding after the observation interval.
# Use this on a level drivetrain test, not an unsupported loaded lift.
stop_drive(COAST)
show_status("Trial ended; coast release")
# =============================================================================
# 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)
First verify directions with supported wheels. For floor trials use a level, clear surface with enough run-out space. Keep speed, run time, load and start position unchanged between modes.
The final coast release is appropriate to this level drivetrain experiment. Do not reuse it on an unsupported loaded lift. If the project is disabled, powered hold must not be treated as a mechanical support.
09 | MEASURE THE STOP, NOT JUST THE WHOLE RUN
| Mode | Trial | Travel after stop command | Observed behaviour |
|---|---|---|---|
| COAST | 1–3 | Measure | Record |
| BRAKE | 1–3 | Measure | Record |
| HOLD | 1–3 | Measure | Record |
Total travel includes acceleration and the timed driving interval, so it does not isolate stopping distance. Identify the moment of the stop command in your recording and measure subsequent movement.
Compare consistency as well as average run-on. Do not force or push a moving robot by hand to test resistance. Any later load test should be planned for the specific mechanism.
10 | SELECT AND JUSTIFY
Drivetrain: compare driver feel, run-on and traction. BRAKE is a useful starting point, but measured results should inform your choice.
Intake: consider whether it should spin down freely or stop collecting immediately.
Lift: HOLD may help retain a position, but mechanical design, limits and support still matter.
Record the chosen setting, the reason and evidence from tests. Recheck after changing gearing, load or wheel type.
CHALLENGES | CHOOSE STOPPING BEHAVIOUR WITH EVIDENCE
- Read the code: identify default settings and explicit stop commands.
- Predict: explain how coast, brake and hold should differ.
- Compare: run three controlled trials for each stopping mode.
- Measure: use video or a consistent method to estimate movement after the stop command.
- Driver feedback: test centred-stick behaviour at low speed, changing only DRIVER_STOP_MODE.
- Justify: select a drivetrain setting based on evidence rather than assuming hold is always best.
- Review mechanisms: document appropriate settings for intake or lift without using the drivetrain release experiment on a loaded mechanism.
Success evidence
A saved project and comparison log showing controlled conditions, stopping observations and a justified choice. You can explain why hold is motor-position control rather than a guaranteed field-position lock.
OFFICIAL REFERENCES
This is an independent learning resource; VEX and VEXcode are trademarks of their respective owners.