IMU¶
An IMU (inertial measurement unit) measures how it turns (gyro) and how it
accelerates (accelerometer). The XIAO IMU sits on the motor bus like one more
motor, with its own ID (100 when it is new). bus.scan() puts it into
bus.sensors, not into bus.motors.
bus = servolab.connect()
print(bus.sensors) # {100: <Imu 100: XIAO IMU>}
imu = bus[100] # like a motor: bus[ID]
fb = imu.read() # everything from the same moment, ONE message
fb.acceleration # [x, y, z] in m/s^2
fb.angular_velocity # [x, y, z] in rad/s
fb.quaternion # orientation [w, x, y, z]
imu.acceleration, imu.angular_velocity and imu.quaternion also work, but
each of them is one message. In a loop, use imu.read() once.
What the values mean¶
- Angular velocity: how fast the IMU turns around its x, y and z axis.
- Acceleration: includes gravity. Lying still, the IMU shows about 9.81 m/s² pointing up (it measures the force that holds it against gravity). When it moves, gravity and its own acceleration add up.
- Quaternion: the IMU's own estimate of its orientation, from gyro and accelerometer together. It turns IMU coordinates into a world frame with z up. There is no compass: the heading (around z) starts at 0 and drifts slowly.
Motors and IMUs together¶
bus.read_feedback() reads all motors and all sensors with one message:
fb = bus.read_feedback()
fb.position # motors, as always
fb.sensors[100].acceleration # the IMU with ID 100
fb.of(100) # as a dict, like fb.of(1) for a motor
Settings¶
imu.gyro_range = 2000 # deg/s: 250, 500, 1000 or 2000
imu.acc_range = 8 # g: 2, 4, 8 or 16
imu.sample_rate = 416 # Hz: 26, 52, 104, 208, 416 or 833
imu.save_to_eeprom() # keep them after power-off
A smaller range measures finer steps, but values beyond it are cut off. The values servolab gives you are in SI units for every setting.