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.
- Измерьте начальные значения линейкой.
- Проверьте прямую:
drive_base.straight(1000)и измерьте реальную дистанцию. - Если робот недоезжает, немного уменьшите
wheel_diameter. - Если переезжает, немного увеличьте
wheel_diameter. - Проверьте поворот:
drive_base.turn(360). - Если недоворачивает, увеличьте
axle_track. - Если переворачивает, уменьшите
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 - направление движения по дуге.