Mam prostą grę rowerową z góry na dół, do której próbuję dodać sterowanie. Chciałbym wiedzieć, w jaki sposób używam kursu przedniego koła, aby określić kurs i prędkość motocykla.
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;
}
Próbowałem zastosować prędkość roweru do przedniego i tylnego koła i użyć różnicy pozycji tam, aby określić kurs roweru, ale opór przedni sprawia, że jest to mylące.
Edytuj na podstawie komentarza madshogo
Odpowiedzi:
Ok, wróciłem z wynikami!
Wypróbowałem dwa podejścia:
Wykorzystując mechanikę ciał stałych do uzyskania równania różniczkowego regulującego ruch środków kół: wejściowymi wartościami „roweru” są moment obrotowy na tylnym kole i kąt koła przedniego, a dane wyjściowe są kinematyką centrów kół. Ale poddałem się, było ciężko!
Próbuję odgadnąć, co dzieje się z geometrycznego punktu widzenia, gdy tylne koło „popycha” przednie koło do przodu, a przednie koło nie jest proste. Ta metoda daje bezpośrednio równanie nieskończenie małych przyrostów (patrz poniżej), z których można uzyskać rzeczywiste równanie różniczkowe. Nie próbowałem manipulować tym pierwszym równaniem, aby uzyskać ODE, ale domyślam się, że uzyskałbym tę samą ODE przy użyciu mechaniki ciał stałych. Po prostu czuje się dobrze.
Notacje i hipotezy:
Jesteśmy w płaszczyźnie z wektorami bazowymi ex i ey .
A jest środkiem tylnego koła. B jest środkiem przedniego koła. Długość roweru L to odległość między A i B . Kąt między oczkiem a wektorem AB wynosi φ . Kąt między AB a przednim kołem wynosi θ .
Intuicyjne uzasadnienie:
Przypuszczamy, że u pewnego natychmiastowego t , A (T) ma prędkość V (t), współliniowe z AB . Dlatego dla nieskończenie małego czasu dt ,
A (t + dt) = A (t) + V (t) .dt .
Przypuszczamy również, że w czasie t przednie koło nie dryfuje, tzn. Prędkość B jest współliniowa z kierunkiem przedniego koła, tj. Tworzy kąt θ z AB . Nazywamy Uθ wektorem jednostek tworzącym kąt θ z AB , tj. Wektorem jednostek o tym samym kierunku co przednie koło.
Dlatego też, w T + dt ,
B (t + dt) = B (t) + λ.Uθ
dla pewnego rzeczywistego, dodatniego λ, tak że długość roweru L jest zachowana:
odległość (A (t + dt), B (t + dt)) = L
Obliczenia:
To ostatnie równanie przekłada się na
norm² (B (t) + λ.Uθ - A (t) - V (t) .dt) = L²
ale B (t) z definicji oznacza A (t) + L.Uφ , więc λ musi spełniać równanie
norm² (L.Uφ + λ.Uθ - V (t) .dt) = L² .
Rozwiązanie jest oczywiście niezależne od φ, ponieważ problem jest taki sam, gdy rower wskazuje kierunek dodatni y . Dlatego jeśli nazwiemy R macierzą obrotu o kącie -φ , λ musi być dodatnim rozwiązaniem
norm² (L.ey; + λ.Uθ - RV (t) .dt) = L² .
Po kilku obliczeniach, jeśli nazwiemy v normą V , otrzymamy
λ = L. (sqrt (1 - (sin (θ). (1-v.dt / L)) ²) - cos (θ)) + v.dt.cos (θ) .
Oto pseudokod, którego użyłem, aby uzyskać powyższą animację (zamiast Uθ , używam u = U (θ + φ), ponieważ było to prostsze):
Jeśli dużo powtórzysz i / lub zwiększysz kąt skrętu, trajektoria jest kołem, co, jak sądzę, jest spójne.
źródło