Симулятор трапецеидального профиля и S-кривой
Сравните трапецеидальный профиль и S-кривую с ограничением рывка: меняйте ограничения и следите за положением, скоростью, ускорением и рывком.
- Категория
- Системы управления
- Время
- 30–60 min
- Платформа
- Браузер · Arduino
01 / Начните здесь
Введение
За каждой командой двигателя скрывается профиль движения. Оно определяет, как ось разгоняется, сколько движется с постоянной скоростью и когда замедляется. Задайте перемещение и возможности машины: лаборатория покажет рядом трапецеидальный профиль и S-кривую, включая случаи, когда все ограничения невыполнимы.
Live lab / Analytic profile planner
Motion profile simulator
Set a move and watch both profiles plan it. Drag the limits to push the move into a triangle, starve the jerk until acceleration never saturates, and read what the S-curve costs.
Four stacked plots share a time axis. Each is the derivative of the one above it, so a corner in velocity becomes a step in acceleration and an impulse in jerk. The trapezoidal profile is drawn in the accent colour, the S-curve alongside it.
- Trapezoidal
- 1.200 s
- S-curve
- 1.300 s
- Jerk cost
- +0.100 s
- Peak speed
- 100 mm/s
- Peak accel
- 500 mm/s²
- Cruise
- 0.700 s
Keyboard: focus the plots, then use Space to play/pause, B to rewind, R to reset, M to cycle which profiles are shown, and F for full screen.
Управление
Расстояние и максимальная скорость описывают нужное перемещение. Ускорение и предел рывка описывают то, что машина действительно может сделать. Лаборатория перепланирует всё при каждом перетаскивании — перед изменением кривых ничего нажимать не нужно.
Отобразить переключает между обоими профилями и каждым по отдельности. Воспроизвести перемещает временной маркер по графикам в реальном времени — это самый быстрый способ почувствовать, что S-кривая заканчивается позже.
Примечание под ограничениями сообщает, когда предел становится недостижимым, и именно поэтому стоит перетаскивать ползунки.
Теория
Четыре графика расположены друг над другом, и каждый является производной предыдущего. Такая компоновка и есть доказательство: излом скорости — это скачок ускорения, а скачок ускорения — импульс рывка. При дифференцировании разрыв не исчезает — он перемещается вниз, пока не становится неограниченным.
Трапецеидальный профиль разгоняется с постоянным ускорением, движется с постоянной скоростью, а затем замедляется. Скорость имеет форму трапеции, ускорение — прямоугольного сигнала, а рывок — набора импульсов на углах. Именно эти импульсы машина воспринимает как удар, на который податливый привод отвечает звоном.
Профиль типа S-кривая ограничивает также рывок. Ускорение нарастает в течение t_j = a_max / j_max, удерживается и снова убывает, поэтому скорость приобретает скруглённые углы. Он обеспечивает ограниченный рывок.
Ни один профиль не может всегда выполнить каждое ограничение. Перемещение короче v²/a никогда не достигает максимальной скорости. S-кривая с максимальной скоростью ниже a²/j никогда не достигает предела ускорения. И то и другое обычно, и оба случая видны здесь.
Алгоритм
Лаборатория решает профиль, а не интегрирует его. Внутри одного сегмента рывок постоянен, поэтому:
a(τ) = a₀ + j·τ
v(τ) = v₀ + a₀·τ + j·τ²/2
x(τ) = x₀ + v₀·τ + a₀·τ²/2 + j·τ³/6
Эти выражения точны, поэтому перемещение попадает точно в цель, а не рядом с ней, и перетаскивание ползунка сразу перепланирует движение.
Выбор пиковой скорости использует одно тождество: разгон скорости нечётно-симметричен относительно середины, поэтому при любой форме он всегда проходит ровно v_peak/2 × duration. Это превращает вопрос «есть ли этап постоянной скорости?» в одно сравнение и позволяет получить пиковую скорость с ограничением расстояния в замкнутом виде — квадратное уравнение, пока ускорение насыщается, и кубический корень после этого.
Исходный код
Небольшой генератор трапецеидального профиля, который можно вставить в скетч. Он возвращает положение, за которым должен следовать ваш контур управления в момент t:
// Target position t seconds into a trapezoidal move of `d` mm.
float profilePosition(float t, float d, float vMax, float a) {
float tAcc = vMax / a;
float dAcc = vMax * vMax / (2 * a);
if (2 * dAcc > d) { // too short to reach vMax
float tPeak = sqrtf(d / a); // triangular profile
if (t >= 2 * tPeak) return d;
if (t < tPeak) return 0.5f * a * t * t;
float left = 2 * tPeak - t;
return d - 0.5f * a * left * left;
}
float tCruise = (d - 2 * dAcc) / vMax;
float tTotal = 2 * tAcc + tCruise;
if (t >= tTotal) return d;
if (t < tAcc) return 0.5f * a * t * t;
if (t < tAcc + tCruise) return dAcc + vMax * (t - tAcc);
float left = tTotal - t;
return d - 0.5f * a * left * left;
}
Вызывайте его один раз за период управления и передавайте результат любому замкнутому контуру. AccelStepper делает эквивалентное внутренне для шаговых двигателей; опции S-кривой там нет, поэтому профиль с ограничением рывка нужно создавать самостоятельно.
Допущения и отличия от реального оборудования
Профили предполагают жёсткую ось без механических ограничений: без трения, люфта, растяжения ремня и потери шагов, а также при наличии пикового тока по запросу. У настоящего шагового двигателя или оси с двигателем постоянного тока момент падает с ростом скорости, податливость превращает рывок в звон, а драйвер насыщается, — поэтому S-кривая помогает манипулятору с ременным приводом, но бесполезно тратит время на коротком жёстком линейном приводе. Здесь частота дискретизации также идеальна; на микроконтроллере точность задаёт стабильность таймера. Читайте перемещение как уставку, за которой должен следовать ваш существующий регулятор, а затем проверяйте его на механике, которую он действительно приводит.
Схема соединений
У этой лаборатории нет уникальной схемы соединений — профиль представляет собой слой арифметики, а не деталь. Он находится между источником команды и уже имеющимся контуром:
target position → PROFILE → setpoint → controller → driver → motor
↑ │
└────── encoder ─────────┘
Соединения — те, которые уже нужны вашему двигателю: драйвер, рассчитанный на пиковый ток разгона, и обратная связь по энкодеру, если вы хотите замкнуть контур. Меняется только уставка, на которую должен выходить регулятор.
Полный вывод, путаница вокруг «рывка» в Marlin и причина того, почему профилирование часто исправляет ПИД-регулятор, который выглядел плохо настроенным, приведены в профилях движения: трапецеидальное ускорение и S-кривая.
Список оборудования
Компоненты
- Шаговый двигатель или двигатель постоянного тока с энкодером
- Драйвер, рассчитанный на пиковый ток, необходимый профилю
- Контроллер с достаточно стабильным таймером для поддержания частоты дискретизации
- Жёсткое крепление — именно податливость превращает рывок в звон
Исследуйте граф
Где используется этот симулятор
Проекты, учебные пути и руководства, которые опираются на эту лабораторию.
Продолжайте сборку
Материалы для загрузки
Пользуйтесь этими справочными материалами на странице, пока работаете над проектом. Загружаемые пакеты проекта появятся только после публикации их исходников и версии.
Частые вопросы
Часто задаваемые вопросы
Почему моя ось никогда не достигает заданной максимальной скорости?
Потому что перемещение слишком короткое. Для достижения максимальной скорости нужен разгон v²/2a и столько же для торможения, поэтому любое перемещение короче v²/a заканчивается до завершения разгона. Профиль скорости становится треугольным, а не трапецеидальным, и его пик равен √(a·d) независимо от настроек. Повышение предела скорости ничего не меняет для таких перемещений — помогает только увеличение ускорения. Перетащите ползунок расстояния ниже порога, и лаборатория сообщит об этом.
Всегда ли S-кривая лучше трапецеидального профиля?
Нет. Она всегда медленнее, и машина не всегда страдает от того, что эта кривая исправляет. S-кривая ограничивает рывок, что важно при наличии податливости в приводе — ремнях, длинных звеньях или тяжёлом инструменте на конце манипулятора, — поскольку скачок ускорения возбуждает эту податливость и вызывает звон. На короткой жёсткой оси с прямым приводом звон может быть неизмерим, а дополнительное время будет чистым потерями. Используйте лабораторию, чтобы увидеть цену, а затем решите, нужна ли вашей машине эта плата.
Сколько времени на самом деле стоит ограничение рывка?
Дополнительное время равно t_j = a_max / j_max, если оба профиля достигают одинаковой максимальной скорости и ускорения. Не два, и — что удивительно — независимо от длины перемещения. Сегмент ускорения S-кривой длиннее, поэтому до начала движения с постоянной скоростью он проходит большее расстояние, а затем этап постоянной скорости сокращается и возвращает большую часть времени. Невозвратимо только само время рывка. Перетащите ползунок расстояния и посмотрите, что стоимость по рывку не меняется.
Почему ускорение никогда не достигает заданного предела?
Потому что предел рывка слишком мал для него. Для разгона до a_max и выхода из него требуется изменение скорости a_max²/j_max, поэтому, если ваша максимальная скорость ниже этого значения, само ускорение становится треугольным и достигает пика √(v·j). Это та же история с «не хватило места», что и при коротком перемещении, только на один порядок производной выше. Лаборатория указывает на это каждый раз, когда такое происходит.
Где профиль находится в моём коде?
До регулятора, а не внутри него. Профиль создаёт уставку — положение, в котором ось должна находиться прямо сейчас, — а всё, что уже есть, следует за ней: планировщик шагов, контур ПИД-регулятора (PID), запись сервопривода. Поэтому профилирование часто исправляет ось, которая казалась плохо настроенной. Ступенчатая команда требует от ПИД-регулятора неограниченного выходного воздействия, поэтому ошибка начинается с полного расстояния перемещения, а интегральная составляющая накапливается при насыщении выхода. С профилированной уставкой ошибка остаётся небольшой, и те же коэффициенты работают нормально.
Дополнительные материалы
Источники
Авторитетные источники, чтобы пойти глубже ограниченной учебной модели этого симулятора.