Ограничения скольжения и антипробуксовка

В физическом движке Cannon.js ограничения скольжения и антипробуксовка реализуются через систему constraint и настройку friction для тел. Эти механизмы позволяют контролировать поведение объектов при контакте с поверхностями, имитируя реалистичное сопротивление движению и предотвращая неконтролируемое проскальзывание.

Фрикция и контактные силы

Каждое тело в Cannon.js имеет свойство material, которое описывает физические характеристики поверхности: коэффициент трения (friction) и коэффициент упругости (restitution). Эти параметры определяют, как объект взаимодействует с другими телами:

const groundMaterial = new CANNON.Material('groundMaterial');
const boxMaterial = new CANNON.Material('boxMaterial');

groundMaterial.friction = 0.8; // высокая фрикция
boxMaterial.friction = 0.4;    // умеренная фрикция

const contactMaterial = new CANNON.ContactMaterial(
  groundMaterial,
  boxMaterial,
  {
    friction: 0.5,      // коэффициент трения между поверхностями
    restitution: 0.1    // упругость контакта
  }
);

world.addContactMaterial(contactMaterial);

Ключевой момент: значение friction на уровне контакта является основным фактором ограничения скольжения. Оно комбинирует свойства обеих поверхностей для точного расчета силы трения.

Ограничение движения по определённой оси

Для имитации антипробуксовки и ограничения скольжения можно использовать constraints, например LockConstraint, HingeConstraint или PointToPointConstraint. Они позволяют ограничивать движение тел в выбранных направлениях.

const hinge = new CANNON.HingeConstraint(carBody, wheelBody, {
    pivotA: new CANNON.Vec3(1, 0, 0),
    axisA: new CANNON.Vec3(0, 1, 0),
    pivotB: new CANNON.Vec3(0, 0, 0),
    axisB: new CANNON.Vec3(0, 1, 0)
});
world.addConstraint(hinge);

Использование HingeConstraint позволяет колесу вращаться вокруг своей оси, но предотвращает смещение в других направлениях, имитируя сцепление с дорогой.

Антипробуксовка через динамическое управление скоростью

Для активной антипробуксовки применяются методы регулирования скорости вращения колес относительно скорости автомобиля. Вычисляется скольжение как разность линейной скорости и касательной скорости вращающегося колеса:

function applyAntiSlip(wheel, chassis) {
    const wheelVelocity = wheel.angularVelocity.length();
    const chassisSpeed = chassis.velocity.length();
    
    const slipRatio = (wheelVelocity - chassisSpeed) / Math.max(chassisSpeed, 0.1);

    const tractionForce = -slipRatio * wheel.mass * 10;
    wheel.applyTorque(new CANNON.Vec3(0, tractionForce, 0));
}

Примечание: отрицательная обратная связь через tractionForce уменьшает проскальзывание, удерживая колесо в пределах сцепления с поверхностью.

Комбинация фрикции и ограничений

Эффективная антипробуксовка достигается через сочетание материалов с высоким трением, constraints, ограничивающих ненужное смещение, и активного регулирования силы вращения. Например, автомобильная физика в Cannon.js обычно использует:

  1. ContactMaterial с точной настройкой friction и restitution.
  2. HingeConstraint для колес.
  3. Регулировку скорости вращения колес для активного контроля скольжения.

Особенности численной стабильности

  • Слишком высокий коэффициент трения (friction > 1) может вызывать дергание и нестабильность.
  • Constraints создают дополнительные уравнения, увеличивая нагрузку на среду интеграции (step). Рекомендуется использовать фиксированный timeStep и тщательно выбирать значения maxForce.
  • Для антипробуксовки важно контролировать angularVelocity колес, иначе корректирующие силы могут вызвать «подпрыгивание» или заваливание тел.

Практическое применение

  • Автосимуляторы: точная антипробуксовка позволяет реализовать поведение машин на скользкой дороге.
  • Робототехника: ограничение скольжения при движении гусениц или колес робота.
  • Игровые физические головоломки: объекты должны перемещаться только по заданным осям, не скатываясь с платформ.

Итоговая структура кода для сцепления и антипробуксовки

// Создание материалов
const wheelMat = new CANNON.Material('wheel');
const roadMat = new CANNON.Material('road');

// Контакт материала
world.addContactMaterial(new CANNON.ContactMaterial(wheelMat, roadMat, {
    friction: 0.6,
    restitution: 0.1
}));

// Создание constraints для колес
const wheelConstraint = new CANNON.HingeConstraint(chassisBody, wheelBody, {
    pivotA: new CANNON.Vec3(...),
    axisA: new CANNON.Vec3(0, 1, 0),
    pivotB: new CANNON.Vec3(...),
    axisB: new CANNON.Vec3(0, 1, 0)
});
world.addConstraint(wheelConstraint);

// Антипробуксовка в update loop
world.addEventListener('postStep', () => {
    applyAntiSlip(wheelBody, chassisBody);
});

Эта комбинация позволяет достичь реалистичного поведения тел, предотвращает неконтролируемое проскальзывание и обеспечивает стабильное взаимодействие с поверхностями.