Overview
The ControlModule class provides a unified interface for controlling all motors on the VEX IQ robotic arm. It manages four motors (base, shoulder, elbow, gripper) with methods for rotation control, current monitoring, and emergency stops.
Source: ~/workspace/source/arm_controller/src/main.py:219
Constructor
__init__()
Initializes all motor hardware components with their port configurations.
control = ControlModule()
Initialized Motors:
Rotates the entire arm base for horizontal scanning Port: Ports.PORT1
Reversed: True (motor direction inverted)
Controls shoulder joint for vertical arm movement Port: Ports.PORT2
Reversed: True
Controls elbow joint for reach extension Port: Ports.PORT3
Reversed: True
Opens and closes gripper for object manipulation Port: Ports.PORT4
Reversed: True
All motors are configured with reversed=True to standardize positive rotation direction across the arm.
Source: main.py:220
Motor Rotation Methods
rotate_motor_forward(motor: Motor, speed: int)
Rotates specified motor in the forward direction at given speed.
# Rotate base motor for scanning
control.rotate_motor_forward(control.base_motor, 20 )
# Raise shoulder
control.rotate_motor_forward(control.shoulder_motor, 60 )
Motor object to rotate. Use one of:
control.base_motor
control.shoulder_motor
control.elbow_motor
control.gripper_motor
Rotation speed in RPM (Revolutions Per Minute)
Range: 1-100 RPM (typical)
Low speeds (1-30): Precise control, scanning
Medium speeds (30-70): Normal operation
High speeds (70-100): Rapid movement
Motor continues rotating until stopped or reversed.
Motor will run indefinitely at specified speed. Always call general_stop() or monitor safety conditions.
Source: main.py:227
rotate_motor_reverse(motor: Motor, speed: int)
Rotates specified motor in the reverse direction at given speed.
# Lower shoulder
control.rotate_motor_reverse(control.shoulder_motor, 10 )
# Open gripper
control.rotate_motor_reverse(control.gripper_motor, 20 )
Motor object to rotate (same as forward method)
Rotation speed in RPM (same range as forward)
Typical Reverse Operations:
Base: Counter-clockwise rotation
Shoulder: Lowering arm
Elbow: Retracting arm
Gripper: Opening claws
Source: main.py:230
Motor Monitoring
get_current_motor(motor: Motor)
Reads the electrical current draw of the specified motor.
current = control.get_current_motor(control.gripper_motor)
if current > 0.3 :
print ( "Gripper has gripped object!" )
control.general_stop()
Current draw in amperes (A)
Idle: ~0.05A
Light load: 0.1-0.2A
Heavy load: 0.3-0.5A
Stall: 0.6A+
Use Cases:
Show Gripper Object Detection
Monitor gripper current to detect when object is gripped: control.rotate_motor_forward(control.gripper_motor, 20 )
while control.get_current_motor(control.gripper_motor) < 0.3 :
time.sleep( 0.05 )
control.general_stop()
print ( "Object secured" )
Detect mechanical obstruction or end-of-travel: control.rotate_motor_forward(control.shoulder_motor, 40 )
current = control.get_current_motor(control.shoulder_motor)
if current > 0.5 :
control.general_stop()
print ( "Mechanical limit reached" )
Estimate object weight or resistance: baseline = control.get_current_motor(control.elbow_motor)
control.rotate_motor_forward(control.elbow_motor, 30 )
time.sleep( 0.5 )
loaded = control.get_current_motor(control.elbow_motor)
load = loaded - baseline
print ( f "Additional load: { load :.2f} A" )
Source: main.py:234
Emergency Stop
general_stop()
Immediately stops all motors on the robotic arm.
# Emergency stop
control.general_stop()
Critical safety method. Called in emergency situations, errors, or task completion.
Stopped Motors:
Base motor
Shoulder motor
Elbow motor
Gripper motor
Behavior:
Stops motors immediately (not gradual deceleration)
Motors enter brake mode (hold position)
No motor movement until new rotation command
Common Triggers:
Bumper sensor activation
Exception handling
Scan completion
Safety check failure
User stop command
Example Safety Pattern:
try :
# Perform operation
control.rotate_motor_forward(control.base_motor, 20 )
# ... operation code ...
except Exception as e:
print ( f "Error: { e } " )
control.general_stop() # Emergency stop
finally :
control.general_stop() # Ensure stopped
Source: main.py:238
Hardware Verification
check_motors()
Verifies that all motors are properly installed and responsive.
if control.check_motors():
print ( "All motors operational" )
else :
print ( "ERROR: Motor installation issue" )
Returns True if all motors installed, False if any motor missing or unresponsive
Checked Motors:
Base motor (Port 1)
Shoulder motor (Port 2)
Elbow motor (Port 3)
Gripper motor (Port 4)
Use Before:
Starting any motor operations
System initialization
After physical maintenance
Source: main.py:244
Port Configuration Summary
Motor Port Direction Primary Function Base PORT1 Reversed Horizontal rotation for scanning Shoulder PORT2 Reversed Vertical arm positioning Elbow PORT3 Reversed Arm reach extension Gripper PORT4 Reversed Object grasping
Motor Speed Guidelines
Base Motor (Scanning)
# Slow scan (high precision)
control.rotate_motor_forward(control.base_motor, 10 )
# Normal scan
control.rotate_motor_forward(control.base_motor, 20 )
# Fast scan (lower precision)
control.rotate_motor_forward(control.base_motor, 40 )
Recommended: 15-25 RPM for object detection
Shoulder Motor (Safety Critical)
# Safety check (with bumper monitoring)
control.rotate_motor_forward(control.shoulder_motor, 60 )
# Slow recovery after bumper hit
control.rotate_motor_reverse(control.shoulder_motor, 10 )
Recommended:
Normal: 40-60 RPM
Recovery: 5-15 RPM
Gripper Motor (Precision)
# Close gripper with current monitoring
control.rotate_motor_forward(control.gripper_motor, 20 )
while control.get_current_motor(control.gripper_motor) < 0.3 :
time.sleep( 0.05 )
control.general_stop()
Recommended: 15-25 RPM to avoid crushing objects
Complete Usage Examples
Initialization and Hardware Check
from vex import *
import time
# Initialize control module
control = ControlModule()
# Verify all motors installed
if not control.check_motors():
print ( "ERROR: Motors not installed properly" )
raise Exception ( "Hardware check failed" )
print ( "All motors operational" )
Environmental Scan
def perform_scan ( control , sensor ):
"""Rotate base 360° for scanning"""
# Start rotation
control.rotate_motor_forward(control.base_motor, 20 )
start_angle = sensor.get_angle()
accumulated_rotation = 0
last_angle = start_angle
while accumulated_rotation < 360 :
current_angle = sensor.get_angle()
# Calculate delta with wraparound
delta = current_angle - last_angle
if delta > 180 :
delta -= 360
elif delta < - 180 :
delta += 360
accumulated_rotation += abs (delta)
last_angle = current_angle
time.sleep( 0.05 ) # 20Hz update
# Stop when complete
control.general_stop()
print ( "Scan complete" )
Safety-Monitored Shoulder Movement
def raise_shoulder_safely ( control , sensor ):
"""Raise shoulder with bumper monitoring"""
control.rotate_motor_forward(control.shoulder_motor, 60 )
while True :
# Check bumper every cycle
if sensor.is_bumper_pressed():
# Emergency stop
control.general_stop()
sensor.set_color(( 255 , 0 , 0 )) # Red error
# Reverse briefly
control.rotate_motor_reverse(control.shoulder_motor, 10 )
time.sleep( 2 )
control.general_stop()
print ( "Bumper collision detected" )
return False
time.sleep( 0.02 ) # 50Hz safety check
return True
Current-Monitored Gripper Control
def close_gripper ( control ):
"""Close gripper until object gripped"""
control.rotate_motor_forward(control.gripper_motor, 20 )
max_time = 5 # 5 second timeout
start_time = time.time()
while time.time() - start_time < max_time:
current = control.get_current_motor(control.gripper_motor)
if current > 0.3 :
control.general_stop()
print ( "Object gripped successfully" )
return True
time.sleep( 0.05 )
# Timeout - no object
control.general_stop()
print ( "No object detected in gripper" )
return False
def open_gripper ( control ):
"""Open gripper fully"""
control.rotate_motor_reverse(control.gripper_motor, 20 )
time.sleep( 1.5 ) # Time to fully open
control.general_stop()
Coordinated Multi-Motor Movement
def position_arm ( control , base_angle , shoulder_angle , elbow_angle ):
"""Move multiple motors to target positions"""
try :
# Start all motors
control.rotate_motor_forward(control.base_motor, 30 )
control.rotate_motor_forward(control.shoulder_motor, 40 )
control.rotate_motor_forward(control.elbow_motor, 30 )
# Wait for positioning (simplified)
time.sleep( 2 )
# Stop all
control.general_stop()
print ( "Positioning complete" )
except Exception as e:
print ( f "Error during positioning: { e } " )
control.general_stop() # Emergency stop
raise
Safety Integration
The ControlModule is used by SafetyModule for critical safety checks:
# From SafetyModule (main.py:254)
class SafetyModule :
def check_shoulder_safety ( self ) -> bool :
if self .sensor_module.is_bumper_pressed():
self .control_module.general_stop() # Emergency stop
self .control_module.rotate_motor_reverse(
self .control_module.shoulder_motor, 10
)
time.sleep( 2 )
self .control_module.general_stop()
return True
return False
def check_gripper_safety ( self ) -> bool :
gripper_current = self .control_module.get_current_motor(
self .control_module.gripper_motor
)
self .control_module.rotate_motor_forward(
self .control_module.gripper_motor, 20
)
if gripper_current > 0.3 :
self .control_module.general_stop()
return True
return False