Servos
Servos are position-controlled actuators used for arms, claws, shields, and other mechanisms.
Declaration
Plain Servo
from libstp import Servo
my_servo = Servo(port=0)
Use plain servos when you only need one or two positions, or when you compute angles dynamically.
Servo with Presets (Recommended)
from libstp import Servo, ServoPreset
claw = ServoPreset(
Servo(port=2),
positions={"closed": 135, "open": 30}
)
arm = ServoPreset(
Servo(port=1),
positions={
"down": 10,
"above_pom": 55,
"up": 105,
"start": 160,
"high_up": 165,
}
)
ServoPreset creates callable methods for each position name. The angle values (0–180) correspond to the servo’s physical range.
Servo Offsets
ServoPreset supports an offset parameter that shifts all positions by a fixed number of degrees:
claw = ServoPreset(
Servo(port=2),
positions={"closed": 135, "open": 30},
offset=5 # Adds 5 degrees to every position
)
This is useful when replacing a broken servo. A new servo mounted on the same shaft may land a few teeth off from the original, causing all positions to be shifted by the same amount. Since all positions are just angle values, adding a constant offset shifts every position by the same amount — no need to re-tune each angle individually.
Tip: When choosing your servo angles, try to avoid values very close to 0 or 180. Keeping some margin (e.g. 10–170) leaves room to apply a positive or negative offset when a servo needs to be swapped at competition — without hitting the physical limits.
Usage in Missions
Preset Servos
# Move to a named position (auto-waits for travel time)
Defs.claw.open()
Defs.claw.closed()
Defs.arm.up()
Defs.arm.down()
# With speed control (degrees per second) — returns a slow servo step
Defs.arm.up(300) # Move to "up" at 300 deg/s
Defs.claw.closed(120) # Move to "closed" at 120 deg/s
When called without an argument, the servo moves at full speed. When called with a number, it moves at that speed in degrees per second — useful for gentle or controlled movements.
Plain Servo
# Move to a specific angle
servo(Defs.my_servo, 90) # Move to 90 degrees
servo(Defs.my_servo, 0) # Move to 0 degrees
Shake Servo
Oscillate between two angles — useful for shaking objects loose:
shake_servo(Defs.claw_servo, duration=2.0, angle_a=30, angle_b=135)
Slow Servo
Move to a position at a controlled speed (degrees per second) — useful for gentle placement. By default, slow_servo uses ease-in-ease-out interpolation, which smoothly accelerates and decelerates the servo for fluid motion:
slow_servo(Defs.my_servo, angle=90, speed=30.0) # 30 degrees/sec (slower than default 60)
Disable All Servos
Turn off all servo outputs (servos go limp):
fully_disable_servos()
Real-World Patterns
Grab and Release
# From ConeBot: grab a cone
seq([
Defs.claw.open(),
Defs.arm.down(),
Defs.claw.closed(120), # Close at 120 deg/s (controlled grip)
Defs.arm.up(120), # Lift at 120 deg/s
Defs.claw.open(60), # Release slowly at 60 deg/s
])
Parallel Servo + Drive
Move servos while the robot is driving:
# From PackingBot: prepare arm while turning
parallel(
turn_right(90),
seq([
Defs.pom_arm.above_pom(),
Defs.pom_grab.open(),
]),
)
Servo Initialization in Setup
Always home your servos in the setup mission so they’re in a known position:
class M00SetupMission(Mission):
def sequence(self) -> Sequential:
return seq([
Defs.claw.closed(),
Defs.arm.up(),
Defs.shield.down(),
Defs.grabber.closed(),
# ... rest of setup
])
Finding Servo Angles
To find the right angle values for each position:
- Open BotUI → Sensors & Actors on the robot’s touchscreen
- Use the servo slider to move the servo manually
- Note the angle when it’s in the position you want
- Enter that angle in your
ServoPresetpositions
Repeat for each named position. The angles depend on how the servo is mounted — there’s no universal “up” or “down” angle.
Timing Considerations
Servo steps block until the servo reaches its target position. When called without a speed argument, the servo moves at full speed and the step estimates travel time based on the angle difference. When called with a speed (degrees per second), it uses a slow servo step that controls the movement rate:
Defs.arm.down() # Full speed, auto-estimated travel time
Defs.arm.down(60) # 60 deg/s — slower, more controlled
Use a slower speed for heavy or delicate mechanisms where full-speed movement could cause problems (slamming, overshooting, dropping objects).