Getting started¶
servolab lets you control Feetech serial bus servos (like the STS3215) from Python. ServoScope, the web app that comes with servolab, is built on top of it: everything you can click there, you can also do in your own code.
Your first lines of code¶
import servolab
bus = servolab.connect() # find the USB adapter and all motors on the cable
print(bus.motors) # {1: <Motor 1: STS3215>, ...}
m = bus[1] # the motor with ID 1 (an ID, not a list index!)
print(m.position) # where is it? in rad
No hardware at hand? servolab.connect("sim") gives you three simulated motors.
servolab.connect("sim:so102") simulates the whole SO102 arm (with gravity and a
3D view) - this needs MuJoCo: pip install "servolab[sim]". See the
Simulation guide.
Moving a motor¶
m.mode = "position" # the motor goes to a goal and holds it
m.torque_enabled = True # power on – the motor now holds its position
m.position = 0.5 # go to 0.5 rad
m.move_to(1.0, speed=2.0, wait=True) # slower, and wait until it arrived
m.torque_enabled = False # power off – you can turn it by hand again
Moving several motors at once¶
The bus has the same two ways, for several motors with ONE message:
bus.write_positions([0.5, -0.5]) # like m.position = ..., sorted like fb.ids
bus.move_to([0.5, -0.5], speed=1.0, wait=True) # like m.move_to(...)
bus.move_to({1: 0.5, 3: 0.0}) # or {motor_id: rad}
bus.move_to() starts all motors together, but each one moves at speed:
a motor with a shorter way arrives earlier.
Reading all motors in a loop¶
rate = servolab.Rate(100) # 100 times per second
while True:
fb = bus.read_feedback() # all motors with ONE message on the bus
print(fb.position) # numpy array, sorted like fb.ids
rate.sleep()
Plotting your measurements¶
rec = servolab.Recorder() # or servolab.LivePlot() to watch live
for _ in range(300):
fb = bus.read_feedback()
rec.add(time=fb.time, position=fb.of(1)["position"])
rate.sleep()
rec.plot() # after the loop: position over time
Don't draw with matplotlib inside your loop: drawing is slow and changes how your controller behaves.
IMUs on the bus¶
An IMU on the cable shows up in bus.sensors and works like a motor:
imu = bus[100], then imu.read().acceleration. bus.read_feedback() reads
motors and IMUs together. See the IMU guide.
ServoScope and your code¶
Only one program can use the USB port at a time. Before you run your own script, press Disconnect in ServoScope (and connect again afterwards).
Where to look things up¶
- Python API: every function and property, with units.
- Registers: the memory table inside the motor.
- Examples: small programs to start from.
In ServoScope these are the tabs of the documentation page; help(m.move_to)
in Python shows the same text.