Рассчитайте курс велосипеда по курсу и скорости переднего колеса

10

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

void Update () 
{
    //Get input from user Vertical: 0 to 1, Horizontal -1 to 1
    float forwardInput = Input.GetAxis("Vertical");
    float sidewaysInput = Input.GetAxis("Horizontal") * m_steeringAmount;

    // Turn front wheel
    m_frontWheelTransform.localEulerAngles = new Vector3(0, sidewaysInput, 90);

    // get speed and drag
    float   speed           = m_velocity.magnitude;
    Vector3 forwardDrag     = -m_forwardDragConstant * m_velocity * speed;

    // calculate acceleration 
    float engineForce       = forwardInput * m_enginePower;
    Vector3 forwardTraction = transform.forward * engineForce;
    Vector3 forwrdForce     = forwardTraction + forwardDrag;
    Vector3 acceleration    = forwrdForce / m_mass;

    // update velocity and position
    m_velocity += acceleration * Time.deltaTime;
    transform.localPosition += m_velocity * Time.deltaTime;
}

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

Редактировать на основе комментария madshogo

введите описание изображения здесь

user346443
источник
Сейчас я разговариваю по телефону, поэтому я просто дам краткий ответ: колеса касаются фиктивного круга, по которому движется велосипед, и поэтому он поворачивается. Центр круга находится на пересечении линий, ортогональных к каждому колесу. Если оба колеса прямые (велосипед не вращается), то эти линии пересекают путь бесконечно далеко (они параллельны), в результате чего образуется круг бесконечного радиуса, то есть линия. В конце концов, это дает вам траекторию, по которой должен следовать велосипед (круг), или его кривизну, в зависимости от того, что соответствует вашим потребностям.
Jrsala
Спасибо за ответ, madshogo. Не могли бы вы взглянуть на диаграмму, которую я добавил, и сказать мне, если это правильно. Красная линия - заголовок велосипеда. Приветствия
user346443
Ой, подождите, переднее колесо не касается круга на вашем рисунке. В моей голове оба колеса были касательными. Это меняет несколько вещей.
Jrsala
Вы видели страницу Википедии по физике велосипедов ? Он имеет полезные формулы для радиуса поворота, которые учитывают наклон.
Сэм Хоцевар

Ответы:

3

Хорошо, я вернулся с результатами!

анимированный велосипед

Я попробовал два подхода:

  • Использование механики твердого тела для получения дифференциального уравнения, управляющего движением центров колес: входы системы «велосипед» - это крутящий момент на заднем колесе и угол наклона переднего колеса, а на выходе - кинематика центров колес. Но я сдался, это было сложно!

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

Обозначения и гипотезы:

Мы находимся в плоскости с базисными векторами ex и ey .

А является центром заднего колеса. B - центр переднего колеса. Длина велосипеда L представляет расстояние между A и B . Угол между ey и вектором AB равен φ . Угол между AB и передним колесом θ .

Интуитивное обоснование:

Мы полагаем , что в некоторый момент времени Т , А (Т) имеет скорость V (T) коллинеарно с AB . Следовательно, для бесконечно малого временного шага dt ,

A (t + dt) = A (t) + V (t) .dt .

Мы также предполагаем, что в момент времени t переднее колесо не дрейфует, то есть скорость B является коллинеарной с направлением переднего колеса, то есть образует угол θ с AB . Мы называем единичным вектором, образующим угол θ с AB , то есть единичный вектор с тем же направлением, что и переднее колесо.

Следовательно, при t + dt ,

B (t + dt) = B (t) + λ.Uθ

для некоторого действительного положительного λ, такого, что длина велосипеда L сохраняется:

расстояние (A (t + dt), B (t + dt)) = L

Расчеты:

Это последнее уравнение переводится как

норма² (B (t) + λ.Uθ - A (t) - V (t) .dt) = L²

но B (t) , по определению, есть A (t) + L.Uφ , так что λ должно удовлетворять уравнению

норма² (L.Uφ + λ.Uθ - V (t) .dt) = L² .

Решение, конечно, не зависит от φ, так как проблема одинакова, когда велосипед указывает на положительное значение y . Следовательно, если мы назовем R матрицей вращения с углом , то λ должно быть положительным решением

norm² (L.ey; + λ.Uθ - RV (t) .dt) = L² .

После нескольких вычислений, если мы назовем v нормой V , вы получите

λ = L. (sqrt (1 - (sin (θ). (1-v.dt / L)) ²) - cos (θ)) + v.dt.cos (θ) .

Вот псевдокод, который я использовал для анимации выше (вместо я использую u = U (θ + φ), потому что это было проще):

// I start at i=1 because i=0 contains the initial values
for (int i=1; i<=N; i++)
{
    // the array in which I stored the successive A points
    Aarray[i] = Aarray[i-1] + dt*V;
    float lambda = L*( sqrt(1 - (sin(theta)*(1-v*dt/L))**2) - cos(theta) )
                   + cos(theta)*v*dt;
    // the array in which I stored the successive B points
    Barray[i] = Barray[i-1] + lambda*u;
    // the AB vector normalized
    AiBiUnit = (Barray[i] - Aarray[i])/L;
    // Refreshing the velocity of A
    V = v*AiBiUnit;
    // Refreshing u.
    // u is indeed a unit vector separated from AiBiUnit by an angle theta,
    // so you get it by rotating the newly computed AiBiUnit by an angle
    // of +theta:
    u = AiBiUnit.rotate(theta);
}

Если вы многократно повторяете и / или увеличиваете угол поворота рулевого колеса, траектория представляет собой круг, который, я считаю, является связным.

jrsala
источник