Xbox Controller Teleoperation¶
Control your Mini-Arm in real-time using an Xbox controller.
Requirements¶
pip install pygame
Controller Setup¶
Connect your Xbox controller via USB or Bluetooth
Verify it’s detected by your OS
Run the demo:
python examples/02_xbox_teleop/teleop.py
Control Mapping¶
Button/Axis |
Action |
|---|---|
Left Stick X |
Base rotation (J0) |
Left Stick Y |
Shoulder (J1) |
Right Stick X |
Wrist yaw (J5) |
Right Stick Y |
Elbow (J2) |
LT / RT |
Gripper close / open |
LB |
Decrease speed |
RB |
Increase speed |
A |
Home position |
B |
Emergency stop |
X |
Toggle Cartesian mode |
Y |
Save waypoint |
Start |
Execute saved trajectory |
Basic Teleop Script¶
from mini_arm import MiniArm
from mini_arm.teleop import XboxController
arm = MiniArm()
arm.connect()
controller = XboxController()
print("Xbox Teleop Active")
print("Press B to stop, A to home")
speed = 50
arm.set_speed(speed)
try:
while True:
# Read controller state
state = controller.get_state()
if state.b_pressed:
print("Stopping...")
break
if state.a_pressed:
arm.home()
continue
# Speed adjustment
if state.lb_pressed:
speed = max(10, speed - 10)
arm.set_speed(speed)
print(f"Speed: {speed}%")
if state.rb_pressed:
speed = min(100, speed + 10)
arm.set_speed(speed)
print(f"Speed: {speed}%")
# Joint control from sticks
arm.jog_joint(0, state.left_stick_x * 2) # Base
arm.jog_joint(1, state.left_stick_y * 2) # Shoulder
arm.jog_joint(2, state.right_stick_y * 2) # Elbow
arm.jog_joint(5, state.right_stick_x * 2) # Wrist
# Gripper
if state.right_trigger > 0.1:
arm.gripper_set(100 - state.right_trigger * 100)
elif state.left_trigger > 0.1:
arm.gripper_set(state.left_trigger * 100)
finally:
arm.disconnect()
controller.close()
Cartesian Mode¶
Toggle to Cartesian control with the X button:
cartesian_mode = False
if state.x_pressed:
cartesian_mode = not cartesian_mode
print(f"Cartesian mode: {cartesian_mode}")
if cartesian_mode:
# Sticks control XYZ position
arm.jog_cartesian(
dx=state.left_stick_x * 5,
dy=state.left_stick_y * 5,
dz=(state.right_trigger - state.left_trigger) * 5
)
else:
# Normal joint control
# ...
Recording Trajectories¶
Use the controller to record and playback trajectories:
waypoints = []
recording = False
if state.y_pressed:
# Save current position as waypoint
current = arm.get_joints()
waypoints.append(current)
print(f"Saved waypoint {len(waypoints)}")
if state.start_pressed and waypoints:
print(f"Executing {len(waypoints)} waypoints...")
arm.execute_trajectory(waypoints, duration=len(waypoints) * 2)
waypoints = []
Deadzone Configuration¶
controller = XboxController(
deadzone=0.15, # Ignore small stick movements
trigger_threshold=0.1, # Trigger activation threshold
)
Vibration Feedback¶
# Vibrate on collision warning
if arm.near_limit():
controller.vibrate(intensity=0.5, duration=0.2)
# Vibrate on waypoint save
if state.y_pressed:
controller.vibrate(intensity=1.0, duration=0.1)
Next Steps¶
Face Tracking - Vision-based control
AI Integration - Natural language commands