Overview
The SafetyModule class provides hardware validation and emergency safety mechanisms for the robotic arm controller. It performs sequential safety checks on critical components and implements immediate stop capabilities to prevent hardware damage.
Location : arm_controller/src/main.py:254
SafetyModule Class
class SafetyModule :
def __init__ ( self , sensor_module : SensorModule, control_module : ControlModule):
self .sensor_module = sensor_module
self .control_module = control_module
self .error_count = 0
self .error_threshold = 3
Dependencies :
SensorModule: Sensor interface for bumper, distance, and LED control
ControlModule: Motor control for emergency stop and safety movements
Error threshold is set to 3 consecutive errors before system halt. This parameter is currently tracked but not actively enforced in safety checks.
Sensor Safety Checks
Hardware Validation
Check Motors
def check_motors ( self ):
return self .control_module.check_motors()
Validates all four motors are installed and operational:
Base motor (PORT1)
Shoulder motor (PORT2)
Elbow motor (PORT3)
Gripper motor (PORT4)
Returns : True if all motors pass, False otherwise
Check Sensors
def check_sensors ( self ):
return self .sensor_module.check_sensors()
Validates critical sensors are installed:
Base distance sensor (PORT11)
Gripper distance sensor (PORT7)
Bumper sensor (PORT12)
Returns : True if all sensors pass, False otherwise
Complete Hardware Check
# Used in RoboticServices.check_service()
if self .safety_module.check_sensors() and self .safety_module.check_motors():
self .sensor_module.set_color(LEDColors. READY )
return True
else :
self .sensor_module.set_color(LEDColors. ERROR )
return False
System will not proceed to safety_service or scan_service if check_service fails. Always validate hardware before operation.
Shoulder Safety Check
Purpose : Validate shoulder mechanism limits using bumper collision detection
def check_shoulder_safety ( self ) -> bool :
if self .sensor_module.is_bumper_pressed():
self .control_module.general_stop()
self .sensor_module.set_color(LEDColors. ERROR )
self .control_module.rotate_motor_reverse( self .control_module.shoulder_motor, 10 )
time.sleep( 2 )
self .control_module.general_stop()
return True
else :
self .control_module.rotate_motor_forward( self .control_module.shoulder_motor, 60 )
self .sensor_module.set_color(LEDColors. WARNING )
return False
Safety Check Flow
Raise Shoulder
Rotate shoulder motor forward at 60 RPM while monitoring bumper sensor
Detect Collision
When bumper is pressed, immediately trigger emergency stop
Reverse Motion
Move shoulder in reverse at 10 RPM for 2 seconds to clear bumper
Final Stop
Stop all motors and return success status
LED Status Indicators
Color Phase Meaning Orange (WARNING) Raising Shoulder moving upward toward limit Red (ERROR) Collision Bumper pressed, emergency stop activated Green (READY) Complete Safety check passed, system ready
Bumper Sensor : Binary switch at shoulder upper limit
Reversal Speed : 10 RPM (slow, controlled movement)
Reversal Duration : 2 seconds
The check returns True only when bumper is pressed and reversal completes. Call repeatedly until True is returned.
Gripper Safety Check
Purpose : Validate gripper mechanism using motor current sensing
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
else :
return False
Current-Based Detection
Read Current
Measure gripper motor current draw
Activate Gripper
Close gripper at 20 RPM while monitoring current
Detect Grip
When current exceeds 0.3A, object is gripped or motor stalled
Emergency Stop
Immediately stop all motors to prevent damage
Current Threshold : 0.3A
Motor Speed : 20 RPM
Detection Method : Current spike indicates grip force or mechanical resistance
Current threshold of 0.3A must be calibrated for specific gripper hardware. Too low may cause false positives, too high may damage objects.
Safety Check Logic
# Used in RoboticServices.safety_state_service()
while self .safety_service_loop == True :
if not self .safety_shoulder:
safety_shoulder = self .safety_module.check_shoulder_safety()
if safety_shoulder:
self .safety_shoulder = True
else :
if not self .safety_gripper:
safety_gripper = self .safety_module.check_gripper_safety()
if safety_gripper:
self .safety_gripper = True
self .safety_service_loop = False
self .safety_mode_active = True
self .sensor_module.set_color(LEDColors. READY )
return True
Emergency Stop Mechanisms
General Stop
Purpose : Immediately halt all motor activity
# In ControlModule
def general_stop ( self ):
self .base_motor.stop()
self .shoulder_motor.stop()
self .elbow_motor.stop()
self .gripper_motor.stop()
Motors Stopped :
Base motor (scanning rotation)
Shoulder motor (vertical positioning)
Elbow motor (arm extension)
Gripper motor (object grasping)
Stop Triggers
Bumper Collision Shoulder hits upper limit switch
Current Overload Gripper motor exceeds 0.3A threshold
Exception Handling Any unhandled exception in main loop
Manual Stop Explicit call to general_stop()
Exception-Triggered Stop
# In RoboticServices.run()
try :
# Service operations
except Exception as e:
self .sensor_module.print_screen( "Error: {} " .format( str (e)[: 20 ]), 1 , 95 )
self .control_module.general_stop()
All exceptions in the main loop trigger emergency stop to ensure system safety. Monitor VEX brain screen for error messages.
LED Status Indicators
Visual feedback through TouchLED sensor (PORT10):
LED Color Definitions
class LEDColors :
ERROR = ( 255 , 0 , 0 ) # Red: Error/Stop
WARNING = ( 255 , 150 , 0 ) # Orange: Warning
READY = ( 0 , 255 , 0 ) # Green: Ready
RUNNING = ( 0 , 0 , 255 ) # Blue: Process Running
OBJECT_DETECTED = ( 0 , 255 , 155 ) # Cyan: Object Detected
Safety State Indicators
State Color RGB Usage ERROR Red (255, 0, 0) Bumper collision, hardware failure, emergency stop WARNING Orange (255, 150, 0) Safety checks in progress, caution state READY Green (0, 255, 0) All checks passed, system operational RUNNING Blue (0, 0, 255) Active scanning or normal operation OBJECT_DETECTED Cyan (0, 255, 155) Object within detection range
LED Control
# In SensorModule
def set_color ( self , color ):
r, g, b = color
self .touchled.set_color(r, g, b)
# Usage in safety checks
self .sensor_module.set_color(LEDColors. ERROR ) # Red on collision
self .sensor_module.set_color(LEDColors. WARNING ) # Orange during check
self .sensor_module.set_color(LEDColors. READY ) # Green when complete
Safety Service LED Sequence
Start - Orange
WARNING color indicates safety checks initiated
Collision - Red
ERROR color when bumper pressed during shoulder check
Complete - Green
READY color when all safety checks pass successfully
Error Handling
Error Count Tracking
class SafetyModule :
def __init__ ( self , sensor_module : SensorModule, control_module : ControlModule):
self .sensor_module = sensor_module
self .control_module = control_module
self .error_count = 0
self .error_threshold = 3
Error counting infrastructure is in place but not currently enforced. Future implementations may halt system after 3 consecutive errors.
Hardware Failure Handling
# In RoboticServices.check_service()
if not check_service:
data = { 'error' : 'Sensors or motors not installed' }
self .communication.send_message( 'check_service' , data)
self .check_mode_active = False
# System will not proceed to other services
Error Response Message :
{
"type" : "check_service" ,
"data" : {
"error" : "Sensors or motors not installed"
}
}
Runtime Error Recovery
try :
# Safety service execution
except Exception as e:
self .sensor_module.print_screen( "Error: {} " .format( str (e)[: 20 ]), 1 , 95 )
self .control_module.general_stop()
# System continues to next loop iteration
Recovery Strategy :
Stop all motors immediately
Display truncated error message on VEX screen
Continue main loop (allows retry or manual intervention)
LED remains in last known state
Safety Service Integration
Sequential Safety Check
# In RoboticServices
def safety_state_service ( self ) -> bool :
while self .safety_service_loop == True :
if not self .safety_shoulder:
safety_shoulder = self .safety_module.check_shoulder_safety()
if safety_shoulder:
self .safety_shoulder = True
else :
if not self .safety_gripper:
safety_gripper = self .safety_module.check_gripper_safety()
if safety_gripper:
self .safety_gripper = True
self .safety_service_loop = False
self .safety_mode_active = True
self .sensor_module.set_color(LEDColors. READY )
return True
return False
Shoulder Safety
Raise shoulder until bumper pressed, then reverse to safe position
Gripper Safety
Close gripper until current threshold reached
Service Complete
Set LED to green and send approval message to Raspberry Pi
Safety State Reset
def reset_safety_sequence ( self ):
self .safety_mode_active = False
self .safety_shoulder = False
self .safety_gripper = False
self .safety_service_loop = True
When to Reset :
Before starting new safety service
After safety service completes
When receiving new safety_service message from Raspberry Pi
Always call reset_safety_sequence() before restarting safety checks to clear previous state flags.
Best Practices
Hardware Validation Always run check_service before any motor operations
Sequential Checks Complete shoulder safety before gripper safety - order matters
Emergency Response Monitor LED color for real-time safety status during operations
State Management Reset safety flags between service runs to avoid stale state
Safety Check Sequence
# Recommended service execution order
serial_manager.send_message( 'check_service' , {}) # 1. Validate hardware
time.sleep( 2 )
serial_manager.send_message( 'safety_service' , {}) # 2. Perform safety checks
time.sleep( 5 )
serial_manager.send_message( 'scan_service' , {}) # 3. Execute scan operation
Calibration Parameters
Shoulder Mechanism
Parameter Value Adjustable Forward Speed 60 RPM Yes Reverse Speed 10 RPM Yes Reverse Duration 2 seconds Yes Bumper Port PORT12 No
Gripper Mechanism
Parameter Value Adjustable Current Threshold 0.3A Yes (recommended) Grip Speed 20 RPM Yes Detection Method Current sensing No
Adjust current threshold based on gripper motor specifications and object grip force requirements. Test with representative objects.
Troubleshooting
Issue Cause Solution Shoulder check never completes Bumper not installed Verify PORT12 connection Gripper check false positive Threshold too low Increase from 0.3A to 0.4-0.5A Emergency stop during scan Bumper sensor malfunction Run check_service to validate hardware LED stays red after check Exception in safety check Check VEX screen for error message
Arm Controller Service orchestration in RoboticServices
Serial Communication Safety service message protocol
Overview Hardware components and LED indicators