
Автомобили встречаются в играх повсеместно, это стандартный элемент многих жанров. Если в игровом мире есть перемещение на дальние расстояния, то есть вероятность, что для него используется автотранспорт (если только вы не в фэнтези-мире, где перемещаются на лошадях. Прощу прощения, но в моём посте не будет информации о программировании лошадей).
Легковые автомобили

С самого детства я играл во множество гоночных и транспортных игр. Я всегда старался находить новые гонки. Но со временем я понял, что меня не просто впечатляют новые машины или трассы; меня привлекала уникальность каждого игрового процесса и поведения машин, несмотря на то, что по сути своей все они были легковыми автомобилями.
Здесь важно сказать следующее: игры — это не физические движки, а впечатления. И гоночные игры больше других намеренно манипулируют реальностью, чтобы дать нам эти впечатления. Например, мы ожидаем от шутеров определённого поведения; пуль, летающих по прямой, отдачу при выстрелах, перезарядку. Если эти ожидания не оправдываются, игра начинает казаться «не такой». Но в случае транспорта степень допущений может быть огромной.
Возьмём для примера Mario Kart. Это гонки, максимально далёкие от реалистичности; машинки дрифтят по песку, вы бросаете в друзей черепашьи панцири и гоняете в картах с мультяшными пропорциями и физикой. Тем не менее, эту игру обожают, ведь она «продаёт» реализацию фантазии о гонках.
На противоположном краю спектра находятся такие реалистичные симуляторы, как iRacing и Assetto Corsa. В них игровой процесс тщательно отточен, чтобы передавать все нюансы и трудности реального автоспорта. Люди тратят тысячи долларов на оборудование, позволяющее воссоздать ощущение нахождения за рулём. Тем не менее, в основе всех этих игр лежит программирование автомобилей. Они лишь по-разному расставляют приоритеты аспектов игрового опыта.
Почему же возможна такая вариативность? Почему играм прощается такой широкий спектр моделей вождения?
Потому что когда дело касается машин, наши ожидания формируются не только из собственных ощущений. Наше понимание того, что такое «ехать быстро», часто основывается на сторонних источниках: фильмах, играх, популярной культуре. Все мы видели, как герой фильма десяток раз переключает передачи в гонке по прямой. Это абсурдно, совершенно непохоже на реальность, но это создаёт у нас некий образ. Это передаёт ощущение ускорения, напряжённости, контроля. Поэтому дети думают, что нужно «переключать передачу», ведь это кажется каким-то значимым действием. Это интуитивное ощущение управления чем-то крупным и тяжёлым на головокружительных скоростях.
Поэтому тот, кто реализует транспорт в игре, первым делом должен задать вопрос «какие ощущения я хочу передать?», а не «какую реальную физику мне нужно симулировать?». И потом уже задаться вопросом «как мне это реализовать?».
Я пришёл к пониманию того, что сложность симуляции транспорта заключается в необходимости соединения двух сложных миров: ощущения и машины. Нужно понимать и тот, и другой. Только тогда вы сможете осознанно выбирать, как и где нарушать правила; потому что гейм-дизайн — это не про симуляцию реальности, а о её подгонке под своё видение.
Погоня за ощущением: итеративный путь к AV Racer
Моей первой попыткой симуляции транспорта в игре стал AV Racer. Изначально это был один спрайт с видом сверху на основе простой ньютоновской модели. Я управлял движением машины ускорением и торможением, привязал угловую скорость к скорости автомобиля (чтобы он не крутился на месте) и на этом закончил.
Похоже это было на машину? В чём-то да. Ощущалось ли это, как машина? Совершенно нет. Больше это напоминало робошайбу, катящуюся по невидимым рельсам. Поэтому я начал итеративно дорабатывать систему, добавив нелинейные кривые и функции сглаживания, чтобы имитировать поведение скользящей машины и избавиться от ощущения движения по рельсам. Я имитировал следы, усилил дрифт, изменил угловой момент. Это не имело ничего общего с реальностью, но почему-то сработало. Пока мою модель не протестировал Кейси Муратори и не сказал, что она похожа на автомобиль на льду или на космический корабль. И он был прав. Она скорее парила, чем двигалась по земле.
Поэтому я вернулся к исследованиям, не отказываясь от своих «хаков»: добавил ещё магических чисел, создал параметр для «скользкости» и продолжал настраивать систему, пока она не стала чёткой, отзывчивой и интересной. Эту финальную версию я выпустил в Steam. Её технический анализ можно прочитать в девлоге на моём веб-сайте.

Но правда в том, что эта машина никогда на самом деле машиной не была. Это был хитрый трюк, чит, попытка вызвать ощущение от вождения без симуляции того, что бы напоминало реальный автомобиль. В определённом смысле модель была нормальной и ломалась только в пограничных случаях. А если бы я показал её водителю гоночного автомобиля или фанату симуляторов, то они бы быстро составили длинный список того, что с ней не так.
Главный вывод из разработки AV Racer был таким:
Если ваша цель — передать ощущения, то можно долго обходиться без реальной физики, и в конечном итоге, возможно, вообще обойтись без неё. Всегда будут возникать пограничные случаи, неприятные моменты, в которые ваша система будет разбивать иллюзию. Но, что более важно, вы останетесь ограниченными отсутствием понимания. Нельзя убедительно трансформировать реальность, если не знать, что вы делаете.
Вернёмся к анализу
После выпуска AV Racer я решил пойти по другому пути. Я хотел сделать всё «правильно» или хотя бы понять, как выглядит это «правильно». А для этого нужно было погружаться глубже. Я начал изучать реальную динамику транспорта, читал, как ведут себя машины в движении и, что столь же важно, как это поведение ощущают водители.
Этот переход от имитации к пониманию изменил всё. Он стал фундаментом для моего следующего проекта и ему я посвятил эту статью: пересечению между тем, как системы работают и как они ощущаются, тому, на что нужно обратить внимание, чтобы реализовать в игре автомобиль.
В процессе попыток написания своего следующего движка я постоянно сталкивался с проблемой снижения «шума» между книгами по физике и большими репозиториями; какие простейшие высокоуровневые концепции мне нужно понять и реализовать, чтобы получить простой автомобиль на прочном физическом фундаменте? Задача этой статьи — помочь разработчику, интересующемуся программированием автомобиля в игре, понять, с чего начинать.
Концептуальная модель симуляции транспортного средства
По сути своей, автомобиль в игре (по крайней мере, тот, который ведёт себя подобно обычному автомобилю) можно разбить на три основных концептуальных компонента:

1. Двигатель (и коробка передач)
Логично начать с этого. Мы считаем, что «перемещает» автомобиль двигатель.
В нашем контексте двигатель включает в себя и коробку передач; вместе они образуют блок, отвечающий за такой ввод игрока, как «газ» и переключение передач. Если не усложнять, то можно сказать, что двигатель получает на входе значение «газа» и преобразует его в скорость вращения и крутящий момент. Затем этот крутящий момент модифицируется текущим передаточным числом и передаётся на ведущие колёса. В то же время сам двигатель тоже учитывает обратную связь от ведущего колеса, он не вращается по отдельности. Происходит двусторонняя синхронизация.
2. Колёса и шины
Здесь физика становится сложнее. Колёса получают крутящий момент от двигателя. На них также влияют другие входные данные: ввод торможения от игрока, поворот рулевого колеса, перенос веса от шасси и, разумеется, трение с дорогой. Эта комбинация определяет, какую величину продольной и поперечной силы могут генерировать шины.
Но это тоже не односторонняя система. Шины тоже влияют на двигатель, потому что скорость колеса определяет скорость двигателя. Существует цикл обратной связи. При симуляции взаимодействия шины с дорогой на помощь приходят модели шин. Именно шины генерируют все силы, действующие на автомобиль. Это единственные точки контакта с дорогой, всё остальное зависит от них.
3. Шасси
Шасси описать проще всего, это не какая-то специфичная для физики автомобилей задача. Шасси — жёсткое тело, привязанное к остальной части физического движка игры. Это тот объект, который движется на самом деле. Он реагирует на силы от шин, а также на внешние влияния, например, на тягу, прижимную силу, гравитацию и коллизии. Шасси влияют на шины, перенося вес между ними в процессе движения и поворотов. Это, в свою очередь, меняет величину сцепления каждой шины с дорогой. То есть здесь тоже присутствует цикл обратной связи.
Компонент |
Входные данные |
Выходные данные |
---|---|---|
Двигатель (с коробкой передач) |
Газ и переключатель скоростей |
Синхронизация колёс с двигателем |
Шины (с колёсами) |
Скорость и крутящий момент двигателя |
Силы, действующие на шасси |
Шасси (с кузовом) |
Силы от колёс |
Вес на колёсах |
Всё это выглядит сложно, и так и есть на самом деле. Но правда заключается в том, что ни одна игра не симулирует всё это полностью точно. Даже самые сложные гоночные симуляторы. Почему? Потому что это попросту непрактично. Понадобился бы полный расчёт динамики жидкости для воздуха и подачи топлива, вычисление в реальном времени термодинамики материала шин, динамика подвески и так далее. Никто этим не занимается, за исключением, возможно, группы автомобильных инженеров, сидящих в лаборатории Porsche в Штутгарте. Поэтому в разработке игр, даже с основанной на физике модели, мы что-то упрощаем.
С некоторыми частями системы мы обращаемся, как с «чёрными ящиками»: формулами, выдающими правдоподобные результаты на основании разумных входных данных. Даже в продвинутых гоночных симуляторах существует абстракция. Она обязана присутствовать.
То есть, в конечном итоге, нет какого-то единственно «верного» способа реализации физики транспорта. Нет ни Библии разработчика, ни опенсорсной «серебряной пули». Каждая игра, каждый движок, каждый разработчик идёт своим путём. Поэтому вы, разработчик, должны осознанно выбирать, что хотите симулировать, что имитировать, а где и жульничать. Невозможно сказать «я создал правильную симуляцию», потому что правильной симуляции нет. Вы должны проектировать систему в соответствии с требованиями своей игры.
Вот псевдокод общего алгоритма того, как происходит цикл физики:
physics step
{
for (each vehicle)
{
update_engine();
for (each wheel)
{
update_tire();
}
update_chassis();
}
...
integrate();
collide_objects();
resolve_contacts();
}
Давайте подробнее рассмотрим первую и, вероятно, концептуально самую «перегруженную» часть:
Двигатель
В реальности двигатель состоит из наибольшего числа подвижных деталей, но в коде это самая простая часть симуляции автомобиля. Потому что по сути своей двигатель — это просто калькулятор крутящего момента. Его задача — сгенерировать единственное выходное значение: крутящий момент на основании входных данных. То есть это просто «чёрный ящик».
Но чтобы сделать всё правильно и чтобы это ощущалось правильно, нам нужно понять механику, лежащую в основе чисел.
Рассмотрим простой пример:

Этап |
RPM (об./мин) |
Кр. момент (Нм) |
Мощность (кВт) |
Сила (Н) |
---|---|---|---|---|
Двигатель |
5000 |
200 |
100 |
— |
Передача (1:3,5) |
1428 |
700 |
100 |
— |
Дифференциал (1:4,1) |
380 |
2870 |
100 |
— |
Колёса (r = 0,3 м) |
380 |
2870 |
100 |
9566 |
Допустим, у нас есть движок, выдающий ровно 100 кВт мощности с 5000 оборотов/мин. Это даёт примерно 200 Нм крутящего момента. Но это слишком большая скорость для колёс. Поэтому между ними есть коробка передач и дифференциал, которые уменьшают скорость, увеличивая крутящий момент. К тому моменту, когда сила достигнет колёс, после передаточного отношения 4,2 и передаточного числа дифференциала 3,8, мы получим что-то около 9500 Н линейной силы (после преобразования крутящего момента в соответствии с радиусом колеса). Это большая нагрузка для пятна контакта. Понимать это необходимо, потому что крутящий момент не постоянен. Он меняется в зависимости от частоты оборотов двигателя и того, как двигатель соединён с ходовой частью.
Если вы занимаетесь тюнингом машин, то узнаете этот график:

Кривая крутящего момента поднимается и снижается рядом с похожей на неё кривой мощности. Эти две «горы» отображают выходные характеристики двигателя в диапазоне его частоты оборотов. Крутящий момент сообщает нам, насколько силён двигатель в конкретной точке. Мощность — это произведение крутящего момента на RPM (с некоторыми константами между ними). У каждого двигателя есть собственная «индивидуальность»: некоторые рано достигают пика и снижения, график других нарастает постепенно и они ревут на высоких оборотах. Эти графики влияют на то, как машина ведёт себя при вождении. Резкий двигатель с высоким крутящим моментом и низким RPM ощущается совершенно иначе, чем ревущий движок с пиком и высоким RPM, пусть даже максимальная скорость обеих машин одинакова.
Основной вывод таков: выходная мощность двигателя различается на разных скоростях.
Допустим, но как нам это симулировать? Как облечь это в код? Нам не нужно симулировать циклы сгорания или реальный крутящий момент на выходе, достаточно кривой, дающей реалистичные значения на основании RPM. Вот, что я сделал: открыл Desmos, посидел в нём час и создал вот этого монстра:
a: изменяет исходные данные кривой y
b: изменяет величину пика
c: изменяет наклон краёв
d: изменяет позицию пика по x
f: изменяет наклон краёв
Я провёл реверс-инжиниринг формулы кривой крутящего момента; не по реальным данным, а по визуальному анализу. Я создал параметры, с которыми можно экспериментировать.
Так я получил свою панель управления. Моя цель заключалась не в идеальной симуляции, а в реалистичных ощущениях и возможности настройки. В результате получился «чёрный ящик» функции, который можно подключить к симуляции двигателя, создающий характер виртуального двигателя. Внеся лишь несколько изменений, можно симулировать всё, от дизельного грузовика до ревущего болида F1:
Коробка передач
С коробкой передач всё очень просто: это таблица передаточных отношений. Каждая передача умножает выходной крутящий момент и делит RPM. Игрок переключает передачи, а мы смотрим на текущее отношение, вот и всё. Но эта механика очень сильно влияет на то, как ускоряется машина. Она определяет профиль ускорения, максимальную скорость и степень свободы, которую вы даёте игроку в достижении идеальных параметров двигателя.
Передача |
Передаточное отношение |
---|---|
R |
-2,92 |
N |
0 |
1 |
2,50 |
2 |
1,61 |
3 |
1,10 |
4 |
0,81 |
5 |
0,68 |

Реализация двигателя и ходовой части: от кривой к коду
Нам нужно обрабатывать две взаимосвязанные ключевые переменные состояния:
RPM двигателя
Угловую скорость ведущего колеса
Двигатель и колёса постоянно перетягивают друг друга в состояние равновесия. Это дифференциальное уравнение, которое нужно решить в коде.
Уравнение двигателя:
: умножается на кривую крутящего момента движка; здесь мы используем аналитическую формулу, о которой говорили выше.
: скалярное значение силы торможения двигателя.
: скалярное значение силы трения и торможения двигателя.
: ввод «газа» игрока.
: ожидаемый RPM при текущей угловой скорости двигателя на текущей передаче из предыдущего кадра.
: текущее значение RPM.
Уравнение ведущего колеса:
: тоже умножается на кривую крутящего момента двигателя.
: скалярное значение силы торможения двигателя.
: скалярное значение силы трения и торможения двигателя.
: ввод тормоза.
: ожидаемая угловая скорость для текущего RPM на текущей передаче.
: текущее значение угловой скорости.
Ключевой аспект разрешения взаимозависимости этих двух переменных заключается в и
. Это удобное решение, предложенное Деметри Спаносом для работы с дифференциальным уравнением.
По сути, оно превращает сопряжённость в два члена, стремящихся к целевому значению. сообщает, насколько сейчас далёк RPM двигателя от требуемого колёсам, а
сообщает, насколько далеки колёса от того, как сейчас двигатель пытается их крутить. Каждая разность становится членом пропорции в соответствующем дифференциальном уравнении, поэтому мы пошагово можем вычислять их в каждом кадре, не решая полную взаимосвязанную систему. Так как на каждом шаге используется только самое новое значение другой переменной, система покадрово сходится к согласованности.
Если вам нужна более тесная взаимосвязь, то вы можете итеративно выполнять по два обновления за кадр и так далее. Для обеспечения стабильности достаточно сохранять малым, чтобы коэффициенты (
) не перескочили нужное значение.
Это решение элегантно тем, что при необходимости можно повышать его сложность. В аркадных играх оно может оставаться простым, а в симуляторах можно добавлять дополнительные слои для большего реализма. Фундамент остаётся тем же: RPM двигателя и угловая скорость колёс взаимосвязаны.
Важно отметить, что к этому решению я пришёл на момент написания статьи. Возможно, вы найдёте более совершенный способ, тогда напишите мне письмо, я с радостью о нём узнаю!
Вот демонстрация из моего движка (включите звук):
Реализовав систему кривой крутящего момента, можно воспользоваться удобством её настройки, чтобы добавить глубины. В этой демонстрации из моего движка можно увидеть знакомые термины из мира автомобильных двигателей: диаметр цилиндров, смещение, профиль распредвала, турбонагнетатель. Ничего этого в физической модели нет. Каждый из этих параметров был сопоставлен с одним из параметров функции кривой крутящего момента. Изменение «cam profile» может привести к смещению пика кривой. Регулируя «displacement», можно повысить базовый крутящий момент. По сути, это просто ручки управления с понятными для игрока надписями. Поэтому хоть это и не настоящая симуляция механики двигателя, она создаёт важное взаимодействие: при изменении параметра вы видите и слышите смену поведения. Это создаёт впечатление, что вы занимаетесь тюнингом реального двигателя. Здесь цель разработчика — не добиться точности, а создать чёткую связь между причиной и следствием: тем, что меняет игрок в игре и как ведёт себя машина.
Кроме того, я привязал эти параметры к звуковой системе, поэтому изменения в движке влияют не только на его характеристики, но и на звуки автомобиля. Благодаря этому при улучшении турбонаддува в магазине игрок не просто получает новые цифры, но и слышит результат.
Модель шин
С двигателем мы разобрались, настала пора переходить к тому, что я считаю самым критичным компонентом гоночной симуляции: шине. Именно на этом этапе все входные данные начинают действовать. А если в гоночной игре неправильно запрограммировать шины, то вся игра будет ощущаться неестественной.
Правильная реализация шин важна, потому что это единственная часть автомобиля, касающаяся дороги. Все силы — ускорения, торможения, поворотов — передаются через это небольшое пятно контакта. Это источник всей обратной связи, управления и физического реализма.
Современные шины — сложное инженерное изделие. Со времени изобретения колеса они прошли долгий путь, и большую роль в нём сыграло открытие и использование вулканизированной резины, позволившей внедрить в систему контролируемую эластичность. Эта эластичность — важнейший аспект того, как шины генерируют силу.
Вот основной принцип:





При контакте резины с асфальтом она немного деформируется под нагрузкой. Эта деформация создаёт силы упругости внутри шины. При движении машины или вращении шины эта упругость сопротивляется усилию сдвига, которое, в свою очередь, создаёт силу сцепления, ускоряющую или поворачивающую машину. Чтобы визуализировать это на микроуровне, представьте, что протектор шины «зацепляется» за текстуру дороги, за крошечные неровности асфальта. Когда шину вдавливает вниз под весом автомобиля (вертикальной силы), она начинает под воздействием этой деформации сцепляться с поверхностью дороги. Пока это взаимодействие находится в пределах эластичности, шина находится в состоянии статического трения, которая обеспечивает автомобилю управляемость и сцепление.
Но эластичность не бесконечна. Если шина начнёт вращаться слишком резко, ускорится слишком сильно или заблокирует тормоза, то пятно контакта деформируется сильнее, чем предел его эластичности. В этот момент шина переходит к динамическому (или кинетическому) трению и начинает скользить по дороге. Тогда сцепление оказывается потерянным, и управлять становится сложнее.
Понимание этого перехода очень важно для симуляции поведения шины при ускорении, торможении и поворотах. И именно это становится самой сложной частью правильного моделирования шин.
Существует максимальная сила, которую шина физически может оказывать на машину при конкретных обстоятельствах, когда достигается предел эластичности шины и она начинает скользить по дороге. Чтобы разобраться в этом, можно разбить сумму сил, генерируемых трением шины по дороге, на продольный и поперечный компоненты. Это отношение можно выразить так:

Продольные силы шины
Для начала здесь нужно понять концепцию статического трения.
Давайте начнём с простого примера: шина катится по дороге с постоянной скоростью, без ускорения и торможения. В этом случае угловая скорость барабана колеса соответствует касательной скорости пятна контакта на дороге. Скольжения нет, одно качение. Шина немного деформируется под действием веса, сцепляется с дорогой благодаря статическому трению, и всё находится в равновесии.

Но что произойдёт, если нажать на газ? С приложением мощности ведущее колесо начинает вращаться быстрее, чем вращается шина сама по себе. Эта разность создаёт кручение в резине. Пятно контакта деформируется: спереди образуются зоны увеличения сжатия, сзади — зоны снижения сжатия. Эта деформация хранит энергию упругой деформации и создаёт силу, толкающую машину вперёд.
Пока показатели находятся в пределах эластичности шины, продолжает действовать статическое трение.

Но если приложить ещё большее усилие (подать больше мощности или снизить сцепление), то рано или поздно эта деформация превзойдёт возможности предела эластичности резины. После этого шина начинает скользить и на неё действует динамическое трение. Этот переход очень важен: на этом этапе сцепление снижается и ухудшается управляемость.

Статическое трение: шина сцепляется с дорогой. Есть деформация, но нет скольжения.
Динамическое трение: сцепление разорвано. Теперь шина скользит по поверхности дороги. После преодоления этого порога величина трения резко снижается.
Коэффициент проскальзывания
Самое интересное происходит в переходе между этими двумя состояниями. Разность между тем, насколько быстро хочет вращаться колесо и насколько быстро машина движется по земле, и определяет продольную силу шины. Эта разность отражается в значении, называемом коэффициентом проскальзывания.
Лично мне этот термин кажется сбивающим с толку. Он подразумевает, что это мера того, насколько шина «скользит», хотя на самом деле это величина деформации в продольном компоненте. Но такая терминология принята в динамике шин, так что мы будем придерживаться её.
Коэффициент проскальзывания — это безразмерная величина, показывающая разность между скоростью вращения колеса и скоростью движения машины по земле. Если они полностью совпадают (не приложена мощность, нет торможения), то коэффициент проскальзывания равен 0. Как только колесо начинает вращаться быстрее (ускорение) или медленнее (торможение), чем движется машина, коэффициент становится ненулевым. И тогда шина начинает деформироваться и создавать полезную силу.
Коэффициент проскальзывания имеет следующее определение:
: угловая скорость свободно катящегося колеса
: угловая скорость ускоряющегося/тормозящего колеса
Или такое:
: угловая скорость ускоряющегося/тормозящего колеса
: радиус колеса, находящегося под нагрузкой
: линейная скорость оси относительно поверхности дороги
(Существует много возможных определений, но все они более-менее отражают одно и то же).
Теперь можно составить график коэффициента проскальзывания относительно продольной силы, генерируемой шиной. В результате мы получим кривую:

При низких коэффициентах тяга увеличивается с большей деформацией; это шина изгибается и сцепляется с дорогой. На пике шина достигает максимума тяги. Вне пределов пика шина продолжает скользить и сила падает; это динамическое трение. Даже при полном скольжении шина всё равно генерирует какую-то силу (то есть при проскальзывании машина всё равно немного движется вперёд). При торможении поведение схоже. Полная блокировка колёс не устраняет всю останавливающую мощность; она просто сильно снижает её эффективность. При торможении кривая обычно снижается плавнее; это вызвано тем, как резина сжимается под воздействием торможения.
Здесь важно уточнить, что ненулевой коэффициент проскальзывания не означает, что шина скользит.
Может иметься средняя величина проскальзывания, а шина всё равно будет находиться в статическом трении; это точка, в которой и начинается настоящее вождение. Весь этот процесс — спектр, а не двоичное состояние. Сцепление плавно переходит от идеального контакта вращения к полному проскальзыванию, и физический движок должен это отражать. Хорошая симуляция происходит в этом промежутке, где шина деформируется, но пока не проскальзывает. Отсюда берутся управляемость, обратная связь и отзывчивость машины.
Если разобраться в физических принципах, то код окажется вполне понятным. Нам нужны:
Способ вычисления коэффициента проскальзывания (разность между вращением шины и скоростью автомобиля).
Функция, превращающая это проскальзывание в коэффициент масштабирования силы.
Чтобы преобразовать коэффициент проскальзывания в кривую, мы используем подход, схожий с тем, который применяли для функции кривой крутящего момента. В данном случае используется формула, выведенная Хансом Пацейкой (1934-2017 гг.). Это нидерландский инженер, занимавшийся динамикой транспорта и ставший легендой в мире моделирования шин. Он преподавал в Делфтском технологическом университете, разработал теорию динамики шин и транспорта, которую активно применяют в проектировании автомобилей. Он вывел «волшебную формулу», также известную как «модель шины Пацейки» — эмпирическое соотношение, отображающее сложное поведение шины в компактной функции из синусов и арктангенсов; оно позволяет полностью управлять поведением шины:
D: изменяет величину кривой
C: изменяет резкость пика
E: изменяет наклон краёв
Если вычислить и настроить это поведение для каждого колеса, то результаты могут быть довольно интересными:
В этом случае задние колёса вращаются существенно быстрее, чем скорость машины. Коэффициент проскальзывания высок, а сила тяги мала; классический пример потери сцепления.
В этом случае есть умеренное контролируемое проскальзывание, потому что игрок плавно прибавляет газ. Колёса и земля остаются достаточно синхронизованными, генерируя большую продольную силу. Это идеальная ситуация для вождения.
Подобные эмерджентные поведения можно получить при корректном моделировании коэффициента проскальзывания. Даже упрощённая модель при правильной реализации может обеспечить обратную связь и реализм, необходимые для создания нужных ощущений от машины.
Поперечные силы шины
Мы поговорили о том, как шины ведут себя в продольном направлении, то есть при торможении и ускорении. Теперь рассмотрим поперечные силы, возникающие при поворотах автомобиля, а если точнее, когда шина поворачивается от направления, в котором двигалась. Когда колесо поворачивается, пятно контакта не остаётся неизменным, а деформируется. Эта деформация, вызванная поперечными нагрузками, и генерирует силу, управляющую поворотами.
Это чётко можно увидеть в записи шины на беговой дорожке, которую поворачивают при качении: чем больше угол, тем сильнее изгибается нижняя часть шины. Важна и нагрузка; чем выше вертикальная сила, вжимающая шину в дорогу, тем сильнее деформация.
Угол проскальзывания
Чтобы правильно симулировать такое поведение, нам нужно разобраться с углами:

На этом графике мы смотрим сверху на переднюю левую шину автомобиля. Кузов автомобиля находится в одном направлении (Dc), шина физически повёрнута в другом (Dw), а вектор истинного движения машины в пространстве (вектор скорости V) может указывать совершенно в другом направлении из-за рыскания, боковых сил и вращения. Из этих векторов мы можем получить два важных угла:
Угол поворота: разность между положением автомобиля и направлением, в котором смотрит шина.
Угол проскальзывания: угол между направлением шины и вектором скорости шины.
Здесь нужно быть внимательными: угол проскальзывания не следует путать с коэффициентом проскальзывания, который связан с вращением колеса в продольном направлении. Угол проскальзывания управляет поперечной силой, коэффициент проскальзывания — продольной. Терминология сбивает с толку, но, к сожалению, это стандарт.
Когда на шину оказывается поперечная нагрузка (например, когда машина поворачивает), резина снова деформируется. Передний край пятна контакта идёт к области полного статического трения, полностью сцепляясь с дорогой. Однако при перемещении по пятну контакта в сторону заднего края возникает градиент деформации, который в определённой точке превосходит пределы эластичности резины. На заднем крае преобладает динамическое трение, и шина начинает скользить.


Эта схема показывает, как нарастает и распределяется поперечная сила внутри пятна контакта шины при повороте. Так как колесо поворачивается на угол проскальзывания, составляющие пятно контакта элементы протектора немного не совпадают по направлению с перемещением. Центральная чёрная линия направления шины отклоняется от пути, по которому она на самом деле движется; эта разность и генерирует поперечную силу.
В пятне контакта протектор переходит от динамического к статическому трению. Посередине резина держится за дорогу и деформируется поперечно, перекручивая каркас шины и накапливая поперечную сдвигающую силу. Эта сила нарастает постепенно, что и отражено в кривой распределения поперечной силы.
Примерно в двух третьих от начала пятна протектор достигает предела сцепления. Дальше он не может поддерживать статический контакт и начинает скользить, снова переходя к динамическому трению. В результате этого поперечная сила сокращается, а шина начинает терять сцепление. Тем временем график поперечной скорости внизу показывает внезапный рост; теперь протектор движется относительно земли.Распределение вертикальной силы на центральном графике раскрывает ещё один слой модели: шина не давит вниз равномерно. Нагрузка распределяется ближе к передней части пятна и уменьшается по направлению к задней части, то есть величина сцепления тоже неравномерна. Это взаимодействие между деформацией и скольжением форму кривой поперечной силы относительно угла проскальзывания: постепенный рост, пик, затем падение; всё это основано на физике пятна контакта.
Сложные модели шин подробно это симулируют, разделяя пятно контакта на множество дискретных зон, каждая из которых имеет свою кривую характеристики. Например, в видео показано, чем занимаются исследовательские группы наподобие Calspan и коммерческие проекты наподобие BeamNG. Но для геймплейных целей обычно такой уровень детализации не нужен, и нам достаточно симулировать одну точку на пятно контакта каждой шины.

В центре пятна преобладает статическое трение. По краям начинается деформация и переход от динамического трения к статическому. С увеличением угла проскальзывания эффективный размер пятна контакта уменьшается, пока шина почти полностью не начинает скользить.
Влияние угла проскальзывания можно видеть в следующих поведениях из реального мира:
Нейтральный поворот: это уравновешенный случай, при котором углы проскальзывания приблизительно равны на передней и задней осях. Благодаря этому машина поворачивает точно так, как планировал водитель. К возникновению такого состояния на средних поворотах часто стремятся при проектировании гоночных автомобилей.
Недостаточная поворачиваемость (Understeer): у передних шин углы проскальзывания выше, чем у задних. Из-за этого они быстрее достигают своего предела сцепления и начинают скользить, из-за чего автомобиль движется по более широкой дуге, чем предполагал ввод управления. Машина сопротивляется повороту, а водитель должен или уменьшить скорость, или увеличить поворот рулевого колеса, чтобы оставаться на нужном курсе.
Чрезмерная поворачиваемость (Oversteer): возникает, когда у задних шин угол проскальзывания больше, чем у передних; они раньше теряют сцепление и начинают скользить наружу, приводя к вылету наружу задней части автомобиля. Это может ощущаться нестабильным или приводить к дрифту, особенно если не скорректировать такое поведение при помощи поворота руля или газа.

Здесь важно то, что не нужно жёстко прописывать эти поведения в своей симуляции. Если ваша модель шины корректно реагирует на угол проскальзывания и нагрузку, то эти характеристики управления возникают из физики естественным образом. В AV Racer для имитации understeer и oversteer я использовал жёстко прописанную логику. Но в этой новой системе они возникают естественно, как результат влияния сил шин, углов проскальзывания и переноса веса, как и в реальном мире.
Как и коэффициент скольжения, поперечная сила тоже образует кривую:

С увеличением угла проскальзывания растёт и поперечная сила. Достигается пик. Вне этого пика сила падает соответственно тому, как всё большая часть пятна контакта переходит к динамическому трению.
На форму этой кривой влияет вертикальная нагрузка на шину. Повышенная нагрузка в общем случае увеличивает величину сцепления, однако это происходит нелинейно. Благодаря этому явлению чувствительности к нагрузке шина по-разному ведёт себя при поворотах, торможении и переносе веса. Как и в случае продольных сил, можно использовать упрощённую функцию для аппроксимации поперечного поведения. Для этого снова можно воспользоваться волшебной формулой Пацейки. Мы вычисляем угол проскальзывания, подставляем его в формулу и получаем скалярное значение, определяющее величину прилагаемой поперечной силы.
Можно заметить, что большая часть этих параметров очень динамична; при работе с ними я пришёл к следующему выводу:
Чем большему количеству параметров вы позволяете меняться динамически и чем больше эти параметры основаны на реальной физике, тем более правдоподобной будет ваша симуляция.
Вот демонстрация из моего игрового движка, где я на лету меняю параметры кривой углов проскальзывания, благодаря чему возникают различные поведения стабильности управляемости, от understeer до oversteer:
Комбинируем продольный и поперечный компоненты
Теперь мы перейдём к тому, что, по моему опыту, оказывается самой концептуально сложной частью симуляции транспорта: пониманию взаимосвязи между продольной и поперечной силами шины и того, как они друг друга ограничивают.
Здесь начинают проявляться недостатки многих упрощённых моделей, а самые реалистичные начинают демонстрировать свою комплексность. На этом этапе шина начинает ощущаться как единая динамическая единица, а не как склеенные друг с другом две отдельные системы сил. Пока мы рассматривали продольную силу (ускорение и торможение) и поперечную силу (повороты) как отдельные системы, у каждой из которых есть свои входные данные, а именно коэффициент проскальзывания и угол проскальзывания. Но на самом деле, каждая шина создаёт один комбинированный вектор силы как функцию от обоих компонентов проскальзывания.

Эти два графика показывают способность шины генерировать изменения в сцеплении, когда ей нужно обрабатывать торможение/ускорение и повороты одновременно. Можно заметить, что шина имеет ограниченный бюджет силы, и использование силы в одном направлении уменьшает допустимую величину в другом.
На графике слева показано, как продольная сила (тяга или торможение) меняется в зависимости от коэффициента проскальзывания при различных углах проскальзывания. При 0° (без поворота) шина может приложить максимальное торможение или ускорение. Но с увеличением угла проскальзывания (то есть при повороте шины) величина продольной силы снижается. При +18° шина так занята поворотом, что у неё остаётся мало сцепления для ускорения или торможения. Именно поэтому резкое торможение посередине поворота может вызывать неустойчивость.
На графике справа показано обратное: изменение поперечной силы (поворота) в зависимости от коэффициента проскальзывания. Максимальное поперечное сцепление возникает, когда шина не находится в условиях резкого торможения или ускорения. С увеличением коэффициента проскальзывания поперечная сила снижается — при больших коэффициентах (например, при заблокированных тормозах) шина едва может поворачивать.
Это иллюстрирует фундаментальный принцип динамики транспорта и гоночных автомобилей: нельзя одновременно тормозить и поворачивать с полной силой. Хорошая модель шин должна учитывать этот баланс.
Теперь рассмотрим график продольных сил и соответствующих коэффициентов проскальзывания на одной оси и поперечной силы с соответствующими углами проскальзывания на другой. График комбинированной силы будет выглядеть так:
Круг трения

Эта менее понятная диаграмма переносит две рассмотренные выше красные кривые на один график координат сил. Вертикальная ось — это продольная сила Fx (вверху тяга, внизу торможение), она размечена соответствующими значениями коэффициентов проскальзывания в логарифмическом масштабе. Горизонтальная ось — это поперечная сила Fy (поворота вправо) с соответствующими отметками углов проскальзывания, тоже на логарифмической шкале.
Это классический круг трения Кулона: в чистой модели Кулона сумма векторов определяет изотропный предел, не зависящий от того, как шина достигла соответствующей нагрузки.
Границы обозначают замеренную пиковую огибающую для конкретной шины. Внутри огибающей красные «спагетти» это угол (дуга) и коэффициент равного проскальзывания (concave), сгенерированные из эмпирических тестовых данных. Двигаясь по одной из этих линий, мы будем наблюдать, что как только шина начнёт выполнять работу в одном направлении, имеющаяся величина сцепления уменьшается не единообразно: поверхность объединённых сил — это не красивый конус и не плавный эллипс, а неровное, зависящее от нагрузок многообразие.
Синий вектор к точке A — это рабочая точка текущего состояния: автомобиль резко поворачивает (примерно 1400 фунтов), в то же время прикладывая умеренный газ (около 200 фунтов). Получающийся результат находится близко к огибающей; небольшое увеличение угла проскальзывания или коэффициента проскальзывания вытолкнет его наружу, приводя к срыву одного компонента силы и к потере управляемости у водителя.
Математически мы можем записать неравенство «бюджета», но графики показывают, что реальные шины распределяют этот бюджет крайне нелинейно и в зависимости от нагрузки и направления. Именно из-за необходимости передачи всех этих изгибов в моделях наподобие магической формулы Пацейки используется по десять с лишним коэффициентов на силу: они позволяют подогнать кривую к тысячам точек реальных данных. Сложность заключается не в сложении векторов, а в подражании неравномерной динамике, скрывающейся в красных линиях, чтобы симулируемая сила набирала и теряла сцепление, а также преобразовывала силы, как это делает физическая шина.
Однако хорошая новость заключается в том, что можно добиться вполне приемлемых результатов, если принять, что шина — это просто круг, и свести все расчёты к этому.
В своей реализации я использовал двухэтапную стратегию:
Вычислял по отдельности продольную и поперечную силы, взяв соответствующие коэффициент и угол проскальзывания в качестве значений для формулы Пацейки.
Нормализовал обе силы, чтобы они умещались в воображаемый круг или эллипс трения. То есть если сумма векторов сил превосходит предел, мы пропорционально уменьшаем их.
Также я изменял сами параметры кривых Пацейки в зависимости от другого компонента проскальзывания. Например, с увеличением угла проскальзывания я уменьшаю пик продольной кривой. Благодаря такому естественному взаимодействию кривых это добавляет реализма.
В любой модели шин сложнее всего реализовать именно эту взаимосвязь, и не существует универсальной аналитической формулы, решающей эту проблему идеально. Многие разработчики симуляций используют проприетарные модели, производители шин полагаются на тестовые стенды. Научные модели, например Пацейки-Шарпа, Derated Fiala, Dugoff — это часть примеров моделей, создающих аппроксимации, со своими плюсами и минусами. Если вы работаете без тестового стенда, то вам придётся полагаться на разумные допущения.
Стоит добавить, что я продолжаю искать наилучшие решения этой проблемы и с радостью выслушаю любую информацию и предложения!
С точки зрения водителя
Телеметрия гоночных автомобилей часто визуализирует эту взаимосвязь при помощи круга перегрузок, и справляется с этим достаточно неплохо. Граница этого круга или эллипса представляет суммарное сцепление шины. Опытный водитель остаётся возле этой границы, не пересекая её; если выйти за неё, то шина перейдёт к полному проскальзыванию, а значит, к потере управления. Пример:

Резкое торможение → высокая продольная перегрузка, низкая поперечная перегрузка.
Средний поворот → высокая поперечная перегрузка, почти без торможения и газа.
Выход из поворота → постепенно повышается газ при разворачивании рулевого колеса.
В этом также заключается логика торможения по дуге, при котором торможение постепенно снижается при увеличении ввода поворота. Водитель плавно сдвигает своё положение на круге движения, используя полный потенциал шин и не перегружая их.
Интеграция в шасси
Сила подвески |
|
Сила тяги |
|
Поперечная сила |
|
Скаляр, зависящий от текущего коэффициента проскальзывания |
|
Скаляр, зависящий от текущего угла проскальзывания |
Это уравнение отражает сумму всех сил, генерируемых одной шиной в одном кадре, передаваемую на шасси в позиции пятна контакта шины. Вертикальная реакция подвески возникает при симуляции одной пружины (в этой статье не рассмотренной, но это не уникальная для симуляции транспорта задача), продольной тяге от ввода тяги/торможения и поперечного сцепления при повороте. Динамическое поведение масштабируется на основании коэффициента и угла проскальзывания, изменённых на коэффициенты и
, отражающих изменение эффективности тяги в зависимости от состояния машины. Эти силы интегрируются в каждом кадре цикла симуляции для вычисления ускорения и обновления скорости шасси по второму закону Ньютона.
Остальная часть машины, то есть шасси — это просто коробка в вашем физическом движке жёстких тел. Вы прикладываете к ней вычисленные силы и наблюдаете, как она двигается, подобно автомобилю.
Если объединить всё описанное выше, то можно получить демонстрацию из моего нынешнего игрового движка:

Всё описанное выше охватывает фундаментальные системы, лежащие в основе симуляции транспорта — поведение двигателя, динамику шин и интеграцию с шасси. Но это лишь самое начало. Возможно, в зависимости от ваших целей вам понадобится исследовать и множество других систем. Например, геометрию подвески, стабилизаторы и амортизаторы, усложнённую динамику шин (например, растяжение, температуру и износ), а также аэродинамику, прижимную силу, различные дифференциальные схемы и модели силовых передач, а также системы управления наподобие ABS и ESP.
Если ваша симуляция требует большой детализации, сфера исследований очень глубока и обширна. Тем не менее, всё рассмотренное нами обеспечит вам надёжную целостную модель машины; она будет вести себя, как автомобиль, а также способна к расширению, если потребуется повышенная точность.
Изучение и исследования в этой области — очень увлекательный процесс, во многом связанный с моим личным опытом и любовью к симулятором авто- и мотогонок, однако большая доля взята из двух книг, которые я определённо рекомендую вам прочитать: Race Car Vehicle Dynamics (авторы Milliken & Milliken) и Mechanics of Pneumatic Tires (автор S.K. Clark).
konst90
Очень грамотно описана часть про двигатель, КПП и крутящий момент. Автор наглядно показал, что важен не момент на моторе, а момент на колесе.
За кадром осталась сложнейшая работа по моделированию подвески. В описанном виде получается абсолютно жёсткая телега с установленными в нулевые углы схода-развала колесами, которая едет по плоскости, причём центр масс этой телеги находится на уровне асфальта. В реальности же колёса у машин установлены "неровно": есть углы схода-развала, то есть отклонения оси колеса от горизонтальной и вертикальной оси. При этом углы эти изменяются в зависимости от силы, которая приложена к колесу, а изменение этих углов приводит к изменению поведения машины, то есть перераспределению этих сил: снова, как и с двигателем, появляется обратная связь. Углы эти меняются и при разгоне, и в повороте. А если трасса не плоская, а имеет уклон, то картина становится ещё веселее.