robotics – Robotics and drive bases

Robotics module for the Pybricks API.

class DriveBase(left_motor, right_motor, wheel_diameter, axle_track)

A robotic vehicle with two powered wheels and an optional support wheel or caster.

By specifying the dimensions of your robot, this class makes it easy to drive a given distance in millimeters or turn by a given number of degrees.

Positive distances, radii, or drive speeds mean driving forward. Negative means backward.

Positive angles and turn rates mean turning right. Negative means left. So when viewed from the top, positive means clockwise and negative means counterclockwise. If desired, you can flip this convention by reversing the left_motor and right_motor when you initialize this class.

See the measuring section for tips to measure and adjust the diameter and axle track values.

Parameters
  • left_motor (Motor) – The motor that drives the left wheel.

  • right_motor (Motor) – The motor that drives the right wheel.

  • wheel_diameter (Number, mm) – Diameter of the wheels.

  • axle_track (Number, mm) – Distance between the points where both wheels touch the ground.

Driving by a given distance or angle

Use the following commands to drive a given distance, or turn by a given angle.

This is measured using the internal rotation sensors. Because wheels may slip while moving, the traveled distance and angle are only estimates.

straight(distance, then=Stop.HOLD, wait=True)

Drives straight for a given distance and then stops.

Parameters
  • distance (Number, mm) – Distance to travel

  • then (Stop) – What to do after coming to a standstill.

  • wait (bool) – Wait for the maneuver to complete before continuing with the rest of the program.

turn(angle, then=Stop.HOLD, wait=True)

Turns in place by a given angle and then stops.

Parameters
  • angle (Number, deg) – Angle of the turn.

  • then (Stop) – What to do after coming to a standstill.

  • wait (bool) – Wait for the maneuver to complete before continuing with the rest of the program.

curve(radius, angle, then=Stop.HOLD, wait=True)

Drives an arc along a circle of a given radius, by a given angle.

Parameters
  • radius (Number, mm) – Radius of the circle.

  • angle (Number, deg) – Angle along the circle.

  • then (Stop) – What to do after coming to a standstill.

  • wait (bool) – Wait for the maneuver to complete before continuing with the rest of the program.

settings(straight_speed, straight_acceleration, turn_rate, turn_acceleration)
settings() Tuple[int, int, int, int]

Configures the speed and acceleration used by straight(), turn(), and curve().

If you give no arguments, this returns the current values as a tuple.

The default values are automatically configured based on your wheel diameter and axle track. They are selected such that your robot drives at about 40% of its maximum speed.

Parameters
  • straight_speed (Number, mm/s) – Straight-line speed of the robot.

  • straight_acceleration (Number, mm/s²) – Straight-line acceleration and deceleration of the robot.

  • turn_rate (Number, deg/s) – Turn rate of the robot.

  • turn_acceleration (Number, deg/s²) – Angular acceleration and deceleration of the robot.

done() bool

Checks if an ongoing command or maneuver is done.

Returns

True if the command is done, False if not.

Drive forever

Use drive() to begin driving at a desired speed and steering.

It keeps going until you use stop() or change course by using drive() again. For example, you can drive until a sensor is triggered and then stop or turn around.

drive(speed, turn_rate)

Starts driving at the specified speed and turn rate. Both values are measured at the center point between the wheels of the robot.

Parameters
  • speed (Number, mm/s) – Speed of the robot.

  • turn_rate (Number, deg/s) – Turn rate of the robot.

stop()

Stops the robot by letting the motors spin freely.

Measuring

distance() int: mm

Gets the estimated driven distance.

Returns

Driven distance since last reset.

angle() int: deg

Gets the estimated rotation angle of the drive base.

Returns

Accumulated angle since last reset.

state() Tuple[int, int, int, int]

Gets the state of the robot.

Returns

Tuple of distance, drive speed, angle, and turn rate of the robot.

reset()

Resets the estimated driven distance and angle to 0.

stalled() bool

Checks if the drive base is currently stalled.

It is stalled when it cannot reach the target speed or position, even with the maximum actuation signal.

Returns

True if the drivebase is stalled, False if not.

Measuring and validating the robot dimensions

As a first estimate, you can measure the wheel_diameter and the axle_track with a ruler. Because it is hard to see where the wheels effectively touch the ground, you can estimate the axle_track as the distance between the midpoint of the wheels.

If you don’t have a ruler, you can use a LEGO beam to measure. The center-to-center distance of the holes is 8 mm. For some tyres, the diameter is printed on the side. For example, 62.4 x 20 means that the diameter is 62.4mm and that the width is 20 mm.

In practice, most wheels compress slightly under the weight of your robot. To verify, make your robot drive 1000 mm using my_robot.straight(1000) and measure how far it really traveled. Compensate as follows:

  • If your robot drives not far enough, decrease the wheel_diameter value slightly.

  • If your robot drives too far, increase the wheel_diameter value slightly.

Motor shafts and axles bend slightly under the load of the robot, causing the ground contact point of the wheels to be closer to the midpoint of your robot. To verify, make your robot turn 360 degrees using my_robot.turn(360) and check that it is back in the same place:

  • If your robot turns not far enough, increase the axle_track value slightly.

  • If your robot turns too far, decrease the axle_track value slightly.

When making these adjustments, always adjust the wheel_diameter first, as done above. Be sure to test both turning and driving straight after you are done.

Using the DriveBase motors individually

After creating a DriveBase object, you can still use its two motors individually. If you start one motor, the other motor will automatically stop. Likewise, if a motor is already running and you make the drive base move, the original maneuver is cancelled and the drive base will take over.

Advanced settings

The settings() method is used to adjust commonly used settings like the default speed and acceleration for straight maneuvers and turns. Use the following attributes to adjust more advanced control settings.

You can only change the settings while the robot is stopped. This is either before you begin driving or after you call stop().

distance_control

The traveled distance and drive speed are controlled by a PID controller. You can use this attribute to change its settings. See the motor control attribute for an overview of available methods. The distance_control attribute has the same functionality, but the settings apply to every millimeter driven by the drive base, instead of degrees turned by one motor.

heading_control

The robot turn angle and turn rate are controlled by a PID controller. You can use this attribute to change its settings. See the motor control attribute for an overview of available methods. The heading_control attribute has the same functionality, but the settings apply to every degree of rotation of the whole drive base (viewed from the top) instead of degrees turned by one motor.

Changed in version 3.2: The done() and stalled() methods have been moved.

Examples

Driving straight and turning in place

from pybricks.pupdevices import Motor
from pybricks.parameters import Port, Direction
from pybricks.robotics import DriveBase

# Initialize both motors. In this example, the motor on the
# left must turn counterclockwise to make the robot go forward.
left_motor = Motor(Port.A, Direction.COUNTERCLOCKWISE)
right_motor = Motor(Port.B)

# Initialize the drive base. In this example, the wheel diameter is 56mm.
# The distance between the two wheel-ground contact points is 112mm.
drive_base = DriveBase(left_motor, right_motor, wheel_diameter=56, axle_track=112)

# Drive forward by 500mm (half a meter).
drive_base.straight(500)

# Turn around clockwise (180 degrees)
drive_base.turn(180)

# Drive forward again to drive back.
drive_base.straight(500)

# Turn around counterclockwise.
drive_base.turn(-180)