Drive Base

DriveBase в Pybricks позволяет управлять двухколесным роботом в миллиметрах и градусах, а не в оборотах моторов.

Инициализация

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

# Подберите направления так, чтобы при положительной скорости робот ехал вперед.
left_motor = Motor(Port.A, Direction.COUNTERCLOCKWISE)
right_motor = Motor(Port.B)

# wheel_diameter и axle_track указываются в мм.
drive_base = DriveBase(left_motor, right_motor, wheel_diameter=56, axle_track=112)

Единицы измерения и знаки

  • Расстояние: миллиметры (mm).
  • Угол поворота: градусы (deg).
  • Линейная скорость: mm/s.
  • Угловая скорость: deg/s.
  • Положительная скорость/дистанция: движение вперед.
  • Положительный угол/turn_rate: поворот вправо (по часовой стрелке, если смотреть сверху).

Основные методы движения

Метод Пример Что делает
straight(distance) drive_base.straight(300) Едет прямо на заданную дистанцию.
turn(angle) drive_base.turn(90) Поворот на месте на заданный угол.
arc(radius, angle=...) drive_base.arc(120, angle=180) Едет по дуге окружности.
arc(radius, distance=...) drive_base.arc(250, distance=400) Едет по дуге на заданную длину.
curve(radius, angle) drive_base.curve(120, 90) Устаревший метод дуги (для старого кода до 3.6).
drive(speed, turn_rate) drive_base.drive(200, 30) Непрерывное движение до stop()/brake().
stop() drive_base.stop() Остановка накатом (coast).
brake() drive_base.brake() Пассивное торможение.

Пример:

drive_base.straight(500)
drive_base.turn(90)
drive_base.arc(120, angle=180)

Режим остановки после маневра (then=Stop...)

Методы straight, turn, arc принимают then=Stop...:

  • Stop.HOLD (по умолчанию): удерживает позицию.
  • Stop.BRAKE: тормозит и не удерживает активно.
  • Stop.COAST: свободный накат.
from pybricks.parameters import Stop

drive_base.straight(300, then=Stop.HOLD)
drive_base.turn(90, then=Stop.BRAKE)
drive_base.arc(150, angle=90, then=Stop.COAST)

Блокирующий и неблокирующий режим

По умолчанию команды ждут завершения (wait=True).
Если нужно выполнять код параллельно с движением, используйте wait=False.

from pybricks.tools import wait

drive_base.straight(800, wait=False)
while not drive_base.done():
    wait(10)

Настройка динамики: settings()

settings() задает параметры только для маневров (straight/turn/arc), но не для drive().

drive_base.settings(
    straight_speed=300,         # mm/s
    straight_acceleration=700,  # mm/s²
    turn_rate=180,              # deg/s
    turn_acceleration=360       # deg/s²
)

print(drive_base.settings())  # кортеж текущих значений

Ограничения settings()

Если задать значения выше физического предела, Pybricks выдаст ошибку.

max_straight_mm_s  = 2000  * π * D / 360
max_straight_mm_s2 = 20000 * π * D / 360
max_turn_deg_s     = 2000  * D / T
max_turn_deg_s2    = 20000 * D / T

Где: * D - диаметр колеса (мм). * T - axle_track, расстояние между колесами (мм).

Расчет для колес 88, 44, 62.4 мм

D (мм) max_straight_mm_s max_straight_mm_s2 max_turn_deg_s max_turn_deg_s2
88 1535.89 15358.90 176000 / T 1760000 / T
44 767.94 7679.45 88000 / T 880000 / T
62.4 1089.09 10890.85 124800 / T 1248000 / T

Пример для T = 112 мм:

D (мм) max_turn_deg_s max_turn_deg_s2
88 1571.43 15714.29
44 785.71 7857.14
62.4 1114.29 11142.86

Телеметрия и состояние

Метод Что возвращает
distance() Пройденную дистанцию с последнего reset() (мм).
angle() Накопленный угол с последнего reset() (градусы).
state() (distance, drive_speed, angle, turn_rate).
done() True, если текущая команда завершена.
stalled() True, если база уперлась/не может выполнить команду.
d, v, a, w = drive_base.state()
print("d:", d, "v:", v, "a:", a, "w:", w)

Сброс одометрии: reset()

drive_base.reset()             # distance=0, angle=0
drive_base.reset(100, -45)     # задать свои стартовые значения

reset() также останавливает текущее движение.

Использование гироскопа: use_gyro()

drive_base.use_gyro(True)   # включить гироскоп для прямолинейности и поворотов
drive_base.turn(360)

drive_base.use_gyro(False)  # только энкодеры моторов

Если хаб установлен нестандартно, задайте top_side и front_side при создании PrimeHub(), иначе углы поворота могут считаться неверно.

Практическая калибровка размеров

Точность DriveBase сильно зависит от wheel_diameter и axle_track.

  1. Измерьте начальные значения линейкой.
  2. Проверьте прямую: drive_base.straight(1000) и измерьте реальную дистанцию.
  3. Если робот недоезжает, немного уменьшите wheel_diameter.
  4. Если переезжает, немного увеличьте wheel_diameter.
  5. Проверьте поворот: drive_base.turn(360).
  6. Если недоворачивает, увеличьте axle_track.
  7. Если переворачивает, уменьшите axle_track.

Сначала калибруйте wheel_diameter, потом axle_track.

curve() и arc(): в чем разница

В Pybricks 3.6+ для нового кода рекомендуется arc().
curve() сохранен для совместимости со старыми проектами.

Сигнатуры

# Старый стиль
drive_base.curve(radius, angle)

# Новый стиль (нужно указать либо angle, либо distance)
drive_base.arc(radius, angle=90)
drive_base.arc(radius, distance=300)

Логика знаков

Метод Что задает radius Что задает angle / distance
curve() (legacy) Направление движения: + вперед, - назад Направление поворота: + вправо, - влево
arc() (актуальный) Сторону дуги: + центр окружности справа, - слева Направление движения: + вперед, - назад

Именно из-за этой разницы старые вызовы с отрицательными значениями при переходе на arc() нужно перепроверять на роботе.

Мини-примеры миграции

# Было (curve): вперед и вправо
drive_base.curve(120, 90)

# Стало (arc): вперед и вправо
drive_base.arc(120, angle=90)
# Было (curve): вперед и влево
drive_base.curve(120, -90)

# Стало (arc): вперед и влево
drive_base.arc(-120, angle=90)

Наглядно: drive_base.arc(radius, angle=...)

Для arc() знак radius выбирает сторону, где находится центр окружности, а знак angle/distance - направление движения по дуге.

Сторона центра (radius)
Направление движения (angle/distance)
центр
сплошная: > 0 (вперед) пунктир: < 0 (назад)
drive_base.arc(120, angle=90) центр справа, едет вперед по дуге