Calcola la direzione della bici dalla direzione della ruota anteriore e dalla velocità


10

Ho un semplice gioco di bici top down a cui sto cercando di aggiungere lo sterzo. Vorrei sapere come utilizzo l'intestazione della ruota anteriore per determinare la direzione e la velocità della bici.

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;
}

Ho provato ad applicare la velocità della bici alla ruota anteriore e posteriore e usare la differenza di posizioni lì per determinare la direzione della bici, ma il trascinamento in avanti la rende confusa.

Modifica in base al commento di madshogo

inserisci qui la descrizione dell'immagine


Al momento sono al telefono, quindi darò solo una breve risposta: le ruote sono tangenti a un cerchio fittizio lungo il quale va la bici, facendo quindi girare la bici. Il centro del cerchio si trova all'intersezione delle linee ortogonali a ciascuna ruota. Se le ruote sono entrambe diritte (la bici non gira), allora queste linee attraversano il percorso infinitamente lontano (sono parallele) risultando in un cerchio di raggio infinito, cioè una linea. Alla fine, questo ti dà la traiettoria che la bici dovrebbe seguire (il cerchio) o la sua curvatura, a seconda delle tue esigenze.
jrsala,

Grazie per la risposta madshogo. Potresti dare un'occhiata al diagramma che ho aggiunto e dirmi se è corretto. La linea rossa indica la direzione della bici. Saluti
user346443

Oh aspetta, la ruota anteriore non è tangente al cerchio nel tuo disegno. Nella mia testa, entrambe le ruote erano tangenti. Ciò cambia alcune cose.
jrsala,

Hai visto la pagina di Wikipedia per la fisica delle bici ? Ha formule utili per il raggio di virata che tengono conto della tendenza.
Sam Hocevar,

Risposte:


3

Ok, sono tornato con i risultati!

bici animata

Ho provato due approcci:

  • Utilizzo della meccanica dei solidi per ricavare un'equazione differenziale che regola il movimento dei centri delle ruote: gli ingressi del sistema "bici" sono la coppia della ruota posteriore e l'angolo della ruota anteriore, e le uscite sono la cinematica dei centri delle ruote. Ma ho rinunciato, è stato difficile!

  • Cercare di indovinare cosa succede da un punto di vista geometrico quando la ruota posteriore "spinge" la ruota anteriore in avanti con la ruota anteriore non diritta. Questo metodo produce direttamente un'equazione di incrementi infinitesimali (vedi sotto) da cui è possibile ottenere un'equazione differenziale effettiva. Non ho provato a manipolare questa prima equazione per ottenere l'ODE ma la mia ipotesi è che avrei ottenuto lo stesso ODE usando la meccanica dei solidi. Sembra giusto.

Notazioni e ipotesi:

Siamo nell'aereo con vettori di base ex e ey .

A è il centro della ruota posteriore. B è il centro della ruota anteriore. La lunghezza della moto L è la distanza tra A e B . L'angolo tra ey e il vettore AB è φ . L'angolo tra AB e la ruota anteriore è θ .

Logica intuitiva:

Supponiamo che, ad un certo istante t , A (t) abbia una velocità V (t) colineare con AB . Pertanto, per un timestep infinitesimale dt ,

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

Supponiamo anche che, al momento t , la ruota anteriore non vada alla deriva, cioè la velocità di B sia in linea con la direzione della ruota anteriore, cioè formi un angolo θ con AB . Chiamiamo il vettore dell'unità formando un angolo θ con AB , ovvero il vettore dell'unità nella stessa direzione della ruota anteriore.

Pertanto, at + dt ,

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

per un certo λ reale, positivo tale da conservare la lunghezza della bici L :

distanza (A (t + dt), B (t + dt)) = L

calcoli:

Quest'ultima equazione si traduce in

norm² (B (t) + λ.Uθ - A (t) - V (t) .dt) = L²

ma B (t) , per definizione, è A (t) + L.Uφ , quindi λ deve soddisfare l'equazione

norm² (L.Uφ + λ.Uθ - V (t) .dt) = L² .

La soluzione, ovviamente, è indipendente da φ poiché il problema è lo stesso quando la bici punta verso y positivo . Pertanto, se chiamiamo R la matrice di rotazione con angolo , λ deve essere la soluzione positiva di

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

Dopo alcuni calcoli, se chiamiamo v la norma di V , ottieni

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

Ecco lo pseudocodice che ho usato per ottenere l'animazione sopra (invece di usare , utilizzo u = U (θ + φ) perché era più semplice):

// 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);
}

Se ripeti molto e / o aumenti l'angolo di sterzata, la traiettoria è un cerchio, che è coerente, credo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.