Calculer le cap du vélo à partir du cap de la roue avant et de la vitesse

10

J'ai un simple jeu de vélo de haut en bas auquel j'essaie d'ajouter de la direction. Je voudrais savoir comment j'utilise le cap de la roue avant pour déterminer le cap et la vitesse du vélo.

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

J'ai essayé d'appliquer la vitesse du vélo aux roues avant et arrière et d'utiliser la différence de positions pour déterminer le cap du vélo, mais la traînée vers l'avant le rend déroutant.

Modifier basé sur un commentaire madshogo

entrez la description de l'image ici

user346443
la source
Je suis en ce moment sur mon téléphone donc je vais juste donner une brève réponse: les roues sont tangentes à un cercle fictif le long duquel va le vélo, faisant donc tourner le vélo. Le centre du cercle est à l'intersection des lignes orthogonales à chaque roue. Si les roues sont toutes les deux droites (le vélo ne tourne pas), ces lignes se croisent infiniment loin (elles sont parallèles), ce qui donne un cercle de rayon infini, c'est-à-dire une ligne. Finalement, cela vous donne la trajectoire que le vélo doit suivre (le cercle) ou sa courbure, selon ce qui convient à vos besoins.
jrsala
Merci pour la réponse madshogo. Pourriez-vous jeter un œil au schéma que j'ai ajouté et me dire si c'est correct. La ligne rouge est le cap du vélo. Vive
user346443
Oh, attendez, la roue avant n'est pas tangente au cercle dans votre dessin. Dans ma tête, les deux roues étaient tangentes. Cela change quelques choses.
jrsala
Avez-vous vu la page Wikipedia pour la physique du vélo ? Il a des formules utiles pour le rayon de virage qui tiennent compte de l'inclinaison.
sam hocevar

Réponses:

3

Ok, je suis de retour avec des résultats!

vélo animé

J'ai essayé deux approches:

  • Utilisation de la mécanique des solides pour dériver une équation différentielle régissant le mouvement des centres des roues: les entrées du système "vélo" sont le couple à la roue arrière et l'angle de la roue avant, et les sorties sont la cinématique des centres des roues. Mais j'ai abandonné, c'était dur!

  • Essayer de deviner ce qui se passe d'un point de vue géométrique lorsque la roue arrière "pousse" la roue avant vers l'avant avec la roue avant non droite. Cette méthode donne directement une équation d'incréments infinitésimaux (voir ci-dessous) à partir de laquelle vous pouvez obtenir une équation différentielle réelle. Je n'ai pas essayé de manipuler cette première équation pour obtenir l'ODE, mais je suppose que j'aurais obtenu ce même ODE en utilisant la mécanique des solides. Ça fait juste du bien.

Notations et hypothèses:

Nous sommes dans l'avion avec les vecteurs de base ex et ey .

A est le centre de la roue arrière. B est le centre de la roue avant. La longueur de la moto L est la distance entre A et B . L'angle entre ey et le vecteur AB est φ . L'angle entre AB et la roue avant est θ .

Justification intuitive:

Nous supposons qu'à un certain instant t , A (t) a une vitesse V (t) colinéaire avec AB . Par conséquent, pour un pas de temps infinitésimal dt ,

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

On suppose également qu'au temps t , la roue avant ne dérive pas, c'est-à-dire que la vitesse de B est colinéaire avec la direction de la roue avant, c'est-à-dire qu'elle forme un angle θ avec AB . On appelle le vecteur unitaire formant un angle θ avec AB , c'est-à-dire le vecteur unitaire de même direction que la roue avant.

Par conséquent, à t + dt ,

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

pour un certain réel, positif λ tel que la longueur du vélo L soit conservée:

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

Calculs:

Cette dernière équation se traduit par

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

mais B (t) , par définition, est A (t) + L.Uφ , de sorte que λ doit satisfaire l'équation

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

La solution est bien sûr indépendante de φ car le problème est le même lorsque le vélo pointe vers y positif . Par conséquent, si nous appelons R la matrice de rotation avec l'angle , λ doit être la solution positive de

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

Après quelques calculs, si nous appelons v la norme de V , vous obtenez

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

Voici le pseudocode que j'ai utilisé pour obtenir l'animation ci-dessus (au lieu d'utiliser , j'utilise u = U (θ + φ) car c'était plus simple):

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

Si vous répétez beaucoup et / ou augmentez l'angle de braquage, la trajectoire est un cercle, ce qui est cohérent, je crois.

jrsala
la source