Симулятор mecanum: боковое движение, скольжение, дрейф
Голономидный робот mecanum едет боком по квадрату: потеряйте сцепление, посмотрите, как ошибаются энкодеры, и установите одно колесо задом наперёд.
- Категория
- Автономные роботы
- Время
- 20–40 min
- Платформа
- Браузер · Arduino · ESP32
01 / Начните здесь
Введение
Колесо mecanum передаёт усилие только под углом 45 градусов: так робот движется боком и теряет сцепление. Лаборатория решает реальный баланс сил с пределом трения, поэтому проскальзывание возникает из физики. Энкодеры интегрируются отдельно от пола, и вы видите, как оценка робота расходится с истиной без возможности заметить это.
Live lab / Holonomic motion
Mecanum drive simulator
Drive a square sideways without ever turning, then take the grip away and watch the encoders keep insisting it worked. Fit one wheel backwards and the same code drives a spiral.
Left: a top-down view of the floor. The dashed outline is the manoeuvre as commanded, the solid line is where the robot actually went, and the dotted line is where its own encoders believe it went. The robot is drawn at its final pose, with each wheel's roller hand hatched — on a correctly built base those hatches point at the centre and make an X. Right: the four wheel rim speeds against time, with the motor's free speed marked. A trace sitting flat on that line is a wheel that has run out of motor; slip shows up on the left instead, as the gap between the solid line and the dotted one.
- Commanded manoeuvre
- Where the robot went
- Where the encoders say
- Motor free speed
- Missed home by
- 0 mm
- Odometry drift
- 0 mm
- Heading change
- 0.0°
- Ground lost to slip
- 0 mm
- Command clipped
- 0%
- Encoder disagreement
- 0.000
Every action has a button above. If you prefer the keyboard, focus the plots and press P for the next preset, M for the next manoeuvre, O to switch between robot- and field-oriented, W to fit the front-left wheel backwards and back, R to reset and F for full screen; sliders respond to the arrow keys.
Управление
Каждый элемент управления повторяет весь манёвр при изменении, поэтому траектория следует за ползунком во время перетаскивания. Нажимать запуск не нужно.
| Элемент управления | Что изменяет |
|---|---|
| Пресет | Пять разобранных ситуаций: одна рабочая и четыре способа перестать работать |
| Манёвр | Что требует водитель: квадрат боком, квадрат с поворотами, диагональный рывок или движение с вращением |
| Скорость стика / вращение стика | Насколько сильно задаётся команда |
| Система координат стика | Связанная с роботом или связанная с полем с IMU |
| Превышение предела | Масштабировать всю команду по худшему колесу или ограничивать каждое отдельно |
| Максимальная скорость колеса | Свободная скорость двигателей на ободе — жёсткий предел независимо от проскальзывания |
| Сцепление пола μ | Полированный бетон имеет примерно 0.8; пыльный пол спортзала или разлитая смазка — 0.25 |
| Посадка колёс | Все четыре правильные или переднее левое установлено задом наперёд |
Левая панель — это пол. Штриховая линия показывает заданный манёвр, сплошная — фактический путь робота, точечная — путь, который, по мнению его собственных энкодеров, прошёл робот. Правая панель показывает скорости обода четырёх колёс во времени с отмеченным пределом двигателя. Траектория, лежащая на этой линии, соответствует колесу, исчерпавшему возможности двигателя; проскальзывание видно на левой панели как промежуток между сплошной и точечной линиями.
Теория
Колесо mecanum может передавать усилие в пол только вдоль осей роликов. В любом другом направлении ролик просто вращается, и ничего не передаётся. Эти оси расположены под 45° к колесу, поэтому сила одного колеса на полу закреплена на одной линии, и никакой момент двигателя её не сдвинет.
Четыре такие линии с чередующимся направлением в сумме дают что угодно. Запишите скорость обода колеса относительно вектора движения шасси ξ = (vx, vy, ω), и получите по одной строке на колесо:
vᵢ = vx + sᵢ·vy + (sᵢ·xᵢ − yᵢ)·ω sᵢ = ±1, the roller hand
Сложите четыре строки в матрицу A, и весь привод будет v = A·ξ. Получаются три следствия, и лаборатория существует, чтобы сделать каждое видимым:
Четыре уравнения, три неизвестных. Жёсткое шасси, все колёса которого сцепляются с полом, не может создавать произвольные скорости обода — лишнее уравнение всегда говорит FL + FR = RL + RR. Невязка этой проверки — бесплатный детектор проскальзывания, который можно вычислить только по энкодерам. Он срабатывает при асимметричном проскальзывании — одно колесо оторвалось от пола, одно стоит на влажном пятне, одно находится не в том углу, — и полностью не замечает случаи, когда скользят все четыре, поэтому ошибка одометрии mecanum накапливается незаметно.
Сцепление стоит 1/√2. Полезная тяга двигателя направлена вдоль качения, но фактическая сила на полу в √2 раз больше и направлена вдоль оси ролика, а трение ограничивает весь вектор. Поэтому предел на колесо равен μN/√2, а предел ускорения робота:
a_max = μ·g / √2
При μ = 0.85 это 5.9 m/s² против 8.3 m/s² у того же робота на обычных колёсах. Масса сокращается в обоих выражениях, поэтому груз ничего не меняет — это противоположность роботу, толкающему груз, где масса и есть стратегия.
Диагонали тоже стоят 1/√2. Команда под 45° подаёт vx + vy на два колеса и ноль на другие, поэтому нагруженная пара насыщается, пока робот движется только со скоростью V_MAX / √2. Более быстрые двигатели поднимают этот предел; ничего его не устраняет.
Полный вывод, включая обратную одометрию, приведён в кинематике колеса mecanum.
Алгоритм
На каждом шаге 5 ms, в таком порядке. Две интеграции позы в конце намеренно разделены — именно это разделение объясняет одометрию.
- Считайте положение стика для текущей точки манёвра.
- При системе координат, связанной с полем, поверните в систему координат робота:
vx' = vx·cos θ + vy·sin θ,vy' = −vx·sin θ + vy·cos θ. При системе координат, связанной с роботом, этот шаг полностью пропускается. - Обратная кинематика —
v = A·ξ, с матрицей, в которую верит прошивка, а она всегда правильная. О неправильно установленном колесе прошивка узнать не может. - Ограничьте — масштабируйте весь вектор по худшему колесу или ограничьте каждое колесо отдельно.
- Запаздывание привода колёс — каждый обод стремится к своей цели с реакцией первого порядка 0.1 s, потому что контур скорости хорош, но не мгновенен.
- То, что требуют колёса, — прямая кинематика методом наименьших квадратов по скоростям обода с матрицей робота, который фактически построен.
- Решите силы, которые согласовали бы шасси, затем примените два предела по порядку: двигателя (момент всегда ограничен) и пола (μN/√2 на колесо).
- Избыточная сила, которую пол не передаёт, вращает обод. Этот избыток ускоряет колесо относительно заданной скорости, то есть создаёт пробуксовку, и это единственный симптом проскальзывания, который энкодер вообще может сообщить.
- Интегрируйте истину от действительно приложенных сил.
- Интегрируйте одометрию по скоростям обода через матрицу прошивки, потому что энкодер прикреплён к колесу, а не к полу.
Ничто здесь не ищет проскальзывание и не вставляет его. Проскальзывание возникает на шаге 7, когда требуемая сила отвергается, а дрейф, который вы видите, — результат того, что шаг 10 так и не узнаёт о нём.
Управляемые эксперименты
Каждый эксперимент изолирует одну переменную. Запускайте их по порядку: они последовательно усложняются.
1. Ради чего вы купили колёса mecanum
Загрузите Квадрат, который сходится. Робот проезжает метр вперёд, метр вправо, назад и влево и возвращается на 17 mm от начальной точки, при этом показание курса не сходит с 0.0°. Затем переключите манёвр на Квадрат с поворотами на углах — тот же квадрат, но выполненный так, как приходится роботу с дифференциальным приводом. Он тоже сходится, до 4 mm. Запомните, что здесь работают оба варианта.
Что наблюдать: квадрат боком перемещается по двум осям и при этом совсем не меняет курс. Ни один привод на дифференциальном принципе не может сделать такое.
2. Заберите пол
Перетащите сцепление пола с 0.85 до 0.25, оставив квадрат боком. Затем сделайте то же самое для квадрата с поворотами.
| Манёвр | Курс при μ = 0.85 | Курс при μ = 0.25 |
|---|---|---|
| Квадрат боком | 0.0° | 0.0° |
| Квадрат с поворотами | 0.2° | десятки градусов, иногда полный разворот |
Что наблюдать: следите за курсом, а не за расстоянием. Оба робота скользят и оба не попадают домой; робот, идущий боком, промахивается, оставаясь точно направленным туда же, куда начал, потому что изначально не задавал вращение. Робот с поворотами теряет курс, а затем едет следующий отрезок в неправильном направлении — так небольшое проскальзывание превращается в большую ошибку. Каждый разворот даёт новую возможность потерять направление, а голономидное шасси просто не допускает их.
Расстояния в этом эксперименте меняются от запуска к запуску при разных настройках, и это честный ответ, а не ошибка: робот, скользящий на всех четырёх колёсах, является системой проскальзывания с трением и не попадает дважды в одно место. С курсом такой проблемы нет.
3. Посмотрите, как врут энкодеры
Загрузите Тот же квадрат, скользкий пол и посмотрите на две линии левой панели. Пунктирная линия одометрии рисует аккуратный квадрат; сплошная — нет. Робот заканчивает в 225 mm от дома, а его собственные энкодеры помещают его в 133 mm в другое место, после того как под колёсами прошло 1.27 m пола, хотя робот вообще не сдвинулся.
Теперь посмотрите на показание Расхождение энкодеров. Всё время оно остаётся 0.000.
Что наблюдать: бесплатная остаточная проверка — FL + FR должно равняться RL + RR на любом жёстком шасси — замечает одно проскальзывающее колесо и полностью слепа к тому, что скользят все четыре. Эта слепота и есть причина, по которой одометрия mecanum тихо отказывает. Установите IMU или опорные колёса и перестаньте доверять энкодерам привода для определения положения.
4. Предел √2
Загрузите Диагональный рывок. Скорость стика 0.60 m/s, как и верхняя скорость колёс, поэтому команда должна быть выполнима. Она не выполнена: команда ограничивается 91% времени, а робот достигает максимума 0.424 m/s — это 0.60/√2 с точностью до трёх знаков после запятой, достигнутый ровно.
Что наблюдать: на правой панели две траектории лежат на нуле, а две закреплены на пределе. Команда под 45° подаёт vx + vy на два колеса и ничего на другие, поэтому нагруженная пара насыщается на V_MAX / √2. Увеличьте максимальную скорость колеса, и предел переместится вместе с ней — 71% не изменится.
5. Масштабирование против ограничения
Переключите манёвр на движение с вращением, увеличьте вращение стика до 240 °/s и переключите Превышение предела между двумя настройками. Форма траектории изменится.
Что наблюдать: масштабирование снижает скорость по каждой оси, но сохраняет направление. Ограничение сохраняет скорость вперёд и теряет 27% вращения — робот поворачивается на 127° за запуск вместо 92° — поэтому закручивается иначе, чем ему предписали. Затем вернитесь к диагональному рывку и попробуйте тот же переключатель: ничего не происходит, потому что нерабочие колёса уже находились внутри предела. Именно так эта ошибка сохраняется после тестирования.
6. Установите колесо задом наперёд
Загрузите Одно колесо установлено задом наперёд или нажмите W на графиках. Код не изменился ни в чём.
| Все четыре правильные | Переднее левое перевёрнуто | |
|---|---|---|
| Промах до дома | 17 mm | более метра |
| Изменение курса | 0.0° | десятки градусов |
| Потеря пола из-за проскальзывания | 15 mm | несколько метров |
| Расхождение энкодеров | 0.000 | ≈ 0.28 |
Что наблюдать: робот больше не делает ничего похожего на заданное, и на этот раз остаточное показание срабатывает — большим и постоянным, а не скачками. Посмотрите, в каком столбце есть точные числа, а в каком нет: когда одно колесо борется с тремя другими, робот непрерывно скользит, поэтому конечная поза хаотична. Остаток — число, которое сохраняется, и именно поэтому его стоит выводить в телеметрию. Это единственный симптом, который можно прочитать на настоящем роботе без IMU и внешнего ориентира. Посмотрите и на нарисованного робота: штриховка перевёрнутого угла направлена не туда, а четыре линии роликов больше не образуют X.
7. Ориентация на поле с одного нажатия
Загрузите пресет Система координат поля с вращением, затем нажмите O, чтобы вернуться к системе координат робота, и ещё раз O, чтобы вернуть систему координат поля.
Что наблюдать: при системе координат, связанной с роботом, удержание стика вперёд во время вращения рисует розетку: робот проходит 2.34 m пути и оказывается в 0.30 m от начальной точки — 13% его усилий ушло в никуда. При системе координат, связанной с полем, тот же стик проходит 2.03 m и оказывается в 2.03 m: совершенно прямая линия, 100%, причём корпус всё время вращается. Шесть строк тригонометрии разделяют эти режимы, и это разница между роботом, которым может управлять человек, и роботом, которым не может управлять никто.
Что следует наблюдать
Если собрать семь выводов вместе:
- Движение вперёд бесплатно; боковое и диагональное — нет. Каждое колесо полностью участвует в движении вперёд. Для диагонали используется половина колёс.
- Два штрафа за корень из двух возникают из одного угла 45°. Это скорость на диагонали и сцепление в каждом направлении. Ни один нельзя купить более мощными двигателями.
- Масса исключается из формулы. Предел ускорения равен μg/√2 независимо от массы робота, что противоположно роботу, толкающему груз.
- Голономидный привод лучше дифференциального при плохом полу, потому что именно развороты дают ошибку.
- Одометрия — это цена. Не проблема настройки и не проблема более качественного энкодера: проскальзывание колёс — это способ работы привода.
Переход к реальному оборудованию
| В этой лаборатории | На настоящем роботе |
|---|---|
| Ползунок сцепления | Один пол и число, которое выясняется, толкая робот напольными весами |
| Колёса достигают заданной скорости с задержкой 0.1 s | Только если вы реализовали контур скорости. При разомкнутом управлении передаточные отношения дрейфуют вместе с батареей |
| Идеальная мгновенная интеграция одометрии | 50–100 Hz, с квантованием энкодеров и переполнением micros(), ожидающим вас |
| Одинаковые двигатели | 3–8% отклонения прямо из коробки и ещё больше при нагреве |
| Чистое μ для всего пола | Пыль, стык линолеума, кабель — местное сцепление меняется сильнее, чем ожидаешь |
| Посадка колёс — выпадающий список | Посадка колёс — это четыре болта и проверка X, и вы однажды ошибетесь |
Лаборатория двадцать минут стоит в основном ради эксперимента 6. Установка колеса задом наперёд здесь ничего не стоит, а на стенде отнимает полдня, и это отказ, который вы наиболее вероятно построите сами.
Исходный код
Весь привод — это две функции. Геометрия находится ровно в одном месте.
const float LX = 0.075f; // half the wheelbase, m (wheel centre to wheel centre / 2)
const float LY = 0.085f; // half the track, m
const float K = LX + LY;
const float R = 0.0485f; // wheel radius, m
const float V_MAX = 0.60f; // rim speed the motors can actually hold, m/s
// Inverse kinematics + saturation. vx forward, vy LEFT, omega counter-clockwise.
void driveMecanum(float vx, float vy, float omega) {
float w[4] = {
vx - vy - K * omega, // front left
vx + vy + K * omega, // front right
vx + vy - K * omega, // rear left
vx - vy + K * omega, // rear right
};
float peak = 0;
for (int i = 0; i < 4; i++) peak = max(peak, fabsf(w[i]));
if (peak > V_MAX) { // SCALE, never clip
float s = V_MAX / peak;
for (int i = 0; i < 4; i++) w[i] *= s;
}
for (int i = 0; i < 4; i++) wheelLoop[i].target = w[i]; // hand to the velocity loops
}
// Forward kinematics for odometry, and the free diagnostic.
float updateOdometry(const float rim[4], float dt) {
float vx = ( rim[0] + rim[1] + rim[2] + rim[3]) * 0.25f;
float vy = (-rim[0] + rim[1] + rim[2] - rim[3]) * 0.25f;
float omega = (-rim[0] + rim[1] - rim[2] + rim[3]) * 0.25f / K;
theta += omega * dt;
poseX += (vx * cosf(theta) - vy * sinf(theta)) * dt;
poseY += (vx * sinf(theta) + vy * cosf(theta)) * dt;
// Four equations, three unknowns. On any rigid, gripping chassis this is zero.
// Large and steady => a wheel is in the wrong corner. Bursty => something slipped.
return (rim[0] + rim[1]) - (rim[2] + rim[3]);
}
Вывод этих четырёх строк и принцип работы остатка приведены в кинематике колеса mecanum. Смысл wheelLoop[i].target создаёт замкнутое управление скоростью колёс. Для сборки используйте робота с приводом mecanum.
Список оборудования
Компоненты
- Четыре колеса mecanum, два левосторонних и два правосторонних — никогда не четыре одинаковых
- Четыре редукторных двигателя, по одному на колесо, каждый с независимым реверсом
- Четыре квадратурных энкодера, если колёса должны сохранять свои передаточные отношения
- Ровный, твёрдый, чистый пол, без которого не обойтись
Исследуйте граф
Где используется этот симулятор
Проекты, учебные пути и руководства, которые опираются на эту лабораторию.
Продолжайте сборку
Материалы для загрузки
Пользуйтесь этими справочными материалами на странице, пока работаете над проектом. Загружаемые пакеты проекта появятся только после публикации их исходников и версии.
Частые вопросы
Часто задаваемые вопросы
Почему мой робот mecanum вращается, когда я прошу его двигаться вбок?
Почти всегда одно колесо стоит не в том углу. В комплекте mecanum есть два левосторонних и два правосторонних колеса, и их ориентация должна чередоваться по шасси. Если одно установлено не туда, его вектор силы направлен поперёк бокового движения, а не вдоль него, поэтому команда боком превращается в медленную дугу с вращением. Движение вперёд всё ещё выглядит нормально, и именно поэтому ситуация так запутывает. Загрузите пресет с одним колесом, установленным задом наперёд: квадрат, который должен был сойтись на 17 mm, оказывается более чем на метр и на десятки градусов повёрнут, хотя код не изменился. Доверять здесь следует расхождению энкодеров: оно меняется с 0.000 примерно до 0.28 — робот, скользящий всеми колёсами, представляет систему сухого трения с прилипанием и проскальзыванием, поэтому точное место остановки нельзя предсказать ни на стенде, ни здесь. Пятисекундная проверка настоящего робота: встаньте над ним, смотрите строго вниз и следите за роликами, видимыми сверху каждого колеса, — эти четыре линии должны быть направлены к центру и образовывать X.
Почему мой робот mecanum медленнее движется по диагонали?
Потому что команда под 45 градусов требует от двух колёс всего, а от двух других — ничего. Установите манёвр на диагональный рывок и посмотрите на график скоростей колёс: две траектории лежат на нуле, а две закреплены на верхнем пределе. Поэтому максимальная диагональная скорость равна максимальной скорости колёс, делённой на корень из двух, то есть примерно 71 процентов скорости прямолинейного движения, а более быстрые двигатели поднимают этот предел, не устраняя его. Это геометрия, а не проблема настройки.
Почему одометрия mecanum так плоха?
Потому что энкодер прикреплён к колесу, а колесо — не пол. На шасси mecanum ролики проскальзывают по конструкции — именно так работает боковое движение, — поэтому каждое проскальзывание колёс учитывается энкодером как перемещение, которого робот не совершал. Загрузите пресет со скользким полом и проедьте квадрат боком: робот заканчивает в 225 mm от дома, его собственная одометрия ошибается на 133 mm, а под колёсами прошло 1.27 m пола, хотя робот не сдвинулся. Ничто на борту не может сообщить об этом. Хуже того, проверка остаточной ошибки, которая замечает одно проскальзывающее колесо, замолкает, когда скользят все четыре, поэтому ошибка накапливается в полной тишине. Поэтому серьёзные конструкции mecanum добавляют IMU для курса и неприводные опорные колёса для положения.
Нужно масштабировать всю команду или ограничивать каждое колесо?
Масштабировать. Ограничение каждого двигателя через constrain() сохраняет скорость, но выбрасывает направление. Установите манёвр «движение с вращением», увеличьте вращение стика до 240 градусов в секунду и переключите ограничитель: масштабирование сохраняет заданный курс и замедляет все оси вместе, а ограничение сохраняет скорость вперёд и тихо теряет больше четверти вращения. Ловушка в том, что на чистой диагонали оба ограничителя дают одинаковые числа, потому что нерабочие колёса уже находятся внутри предела, поэтому ошибка проходит проверку, которую запускают все, и позже проявляется как робот, выходящий из поворотов.
Получает ли более тяжёлый робот лучшее сцепление на колёсах mecanum?
Не при разгоне. Большая масса пропорционально увеличивает и трение, и инерцию, и они полностью сокращаются: предел ускорения равен μ g, делённому на корень из двух, независимо от массы робота. Это противоположность роботу-сумо, где масса — вся стратегия, потому что там перемещаемая нагрузка внешняя. Груз на шасси mecanum не даёт ничего, кроме более медленной реакции двигателей и более плоской разрядной характеристики аккумулятора.
Именно так работает настоящий робот mecanum?
Кинематика точная — это та же матрица из четырёх строк, которую использует любая настоящая реализация, а преобразование для одометрии получается обращением матрицы методом наименьших квадратов. Динамика на каждом шаге решает настоящий баланс сил с двумя пределами по порядку: двигателя и пола, а проскальзывание — это избыточная сила, которую пол не передаёт, а не заранее заданный сценарий. Модель не учитывает контакт каждого ролика по отдельности при его входе на пол и выходе, небольшую вертикальную волну, которую это создаёт, или перенос массы при ускорении. Поэтому она даёт правильные инженерные ответы — штрафы за корень из двух, направление дрейфа одометрии, последствия колеса задом наперёд, — но работает немного плавнее настоящего робота на настоящем полу. Одна честная оговорка: когда скользят все колёса, модель становится системой сухого трения Кулона с прилипанием и проскальзыванием, и точная конечная поза перестаёт быть повторяемым числом, хотя сама лаборатория полностью детерминирована. Расстояние проскальзывания, невязка по энкодерам и все случаи сцепления надёжны; эксперимент с проскальзыванием всех колёс показывает размер проблемы, а не место остановки робота.
Дополнительные материалы
Источники
Авторитетные источники, чтобы пойти глубже ограниченной учебной модели этого симулятора.