У меня есть простая игра на велосипеде сверху вниз, к которой я пытаюсь добавить рулевое управление. Я хотел бы знать, как я использую курс переднего колеса, чтобы определить курс и скорость велосипеда.
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
Ответы:
Хорошо, я вернулся с результатами!
Я попробовал два подхода:
Использование механики твердого тела для получения дифференциального уравнения, управляющего движением центров колес: входы системы «велосипед» - это крутящий момент на заднем колесе и угол наклона переднего колеса, а на выходе - кинематика центров колес. Но я сдался, это было сложно!
Попытка угадать, что происходит с геометрической точки зрения, когда заднее колесо «толкает» переднее колесо вперед, а переднее колесо не является прямым. Этот метод напрямую выдает уравнение бесконечно малых приращений (см. Ниже), из которого вы можете получить фактическое дифференциальное уравнение. Я не пытался манипулировать этим первым уравнением, чтобы получить 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 . Мы называем Uθ единичным вектором, образующим угол θ с 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 = U (θ + φ), потому что это было проще):
Если вы многократно повторяете и / или увеличиваете угол поворота рулевого колеса, траектория представляет собой круг, который, я считаю, является связным.
источник