Archives pour la catégorie Théorie

Principe fondamental de la dynamique

Introduction


La seconde loi de Newton (le principe fondamental de la dynamique) dit que la somme des forces \vec{F} sur un corps est égale à la masse m du corps multipliée par l’accélération \vec{a} du corps:

\sum{\vec{F}}=m.\vec{a}

Cet article illustre la mise en oeuvre du principe fondamental de la dynamique sur un exemple très simple et accessible. Dans la suite de cet article, nous considérerons un corps en mouvement sur un plan incliné:

Overview

L’objectif ici est de calculer l’accélération du corps. Nous supposerons les hypothèses suivantes:


  • Les frottements sont négligés.

  • La force agissant sur le corps est la gravité à la surface de la terre \vec{g}.

  • G est le centre de gravité du corps.

  • m est la masse du corps.

  • \theta est l’angle du plan incliné.

Approche élémentaire


Cette première approche est la plus simple, nous exploiterons l’hypothèse que le corps ne peut se déplacer que dans la direction du plan incliné. En s’appuyant sur cette hypothèse, toutes les forces peuvent être projetées dans la direction du plan incliné. L’application du principe fondamental de la dynamique nous donne:

 m.\vec{a} = \sum{\vec{F}} = \vec{R} + \vec{F_g} = \vec{F_m}

Les forces agissant sur le corps sont la force de gravité \vec{F_g} et la force de réaction du sol \vec{R}. Comme \vec{R} est perpendiculaire au plan incliné, sa projection le long de la direction de déplacement est nulle. La projection de \vec{F} le long du plan incliné est donnée par:

 \| \vec{F_{m}} \| = \|\vec{F_g}\| . sin(\Theta)

Nous pouvons en déduire que :

  m.\|\vec{a} \| = \|\vec{F_g}\| . sin(\Theta) = m.g.sin(\Theta)

Notons que cette équation peut être simplifiée par une division par m. Cela démontre que le mouvement est indépendant de la masse. Beaucoup pensent que plus on est lourd, plus la chute est rapide. Mais en réalité la vitesse de chutte est dépendante des frottements et de la gravité. L’accélération est donc données par:

 \| \vec{a} \| = g.sin(\Theta)

Si le plan est horizontal, \Theta=0, l’accélération du corps est nulle, le corps ne bouge pas. Si le plan incliné est vertical, \Theta=\pi/2, l’accélération du corps est égale à la gravité g, Le corps est en chute libre.

Approche générale

Dans la section précédente, nous avons émis une hypothèse sur la direction du déplacement. Dans celle-ci, nous allons supposé cette direction comme étant inconnue.Les forces agissant sur le corps sont la force de gravité \vec{F_g} et la force de réaction du sol \vec{R}. Nous allons projeter ces forces le long des axes \vec{x} et \vec{y}. La projection de la force de gravité est donnée par:

 \vec{F_g}= \left( \begin{array}{r c l} \vec{F_x} \\ \vec{F_y} \end{array} \right)  = \left( \begin{array}{r c l} 0 \\ -m.g \end{array} \right)

La projection de la force de réaction du sol est donnée par:

 \| \vec{R} \| = m.g.cos(\Theta)
 \vec{R}= \left( \begin{array}{r c l} \vec{R_x} \\ \vec{R_y} \end{array} \right)  = \left( \begin{array}{r c l} -m.g.cos(\Theta).sin(\Theta) \\ m.g.cos(\Theta).cos(\Theta) \end{array} \right)

Comme précédemment, le principe fondamental de la dynamique nous donne:

 m.\vec{a} = \sum{\vec{F}} = \vec{R} + \vec{F_g} = \vec{F_m}
 m.\vec{a}= \left( \begin{array}{r c l} \vec{F_x}+\vec{R_x} \\ \vec{F_y}+\vec{R_y} \end{array} \right)  = \left( \begin{array}{r c l} -m.g.cos(\Theta).sin(\Theta) \\ -m.g+m.g.cos(\Theta).cos(\Theta) \end{array} \right)
 \vec{a}= g.\left( \begin{array}{r c l} -cos(\Theta).sin(\Theta) \\ cos(\Theta)^2-1 \end{array} \right) = g.\left( \begin{array}{r c l} -sin(\Theta).cos(\Theta) \\ -sin(\Theta).sin(\Theta) \end{array} \right)

Ce résultat confirme que l’accélération est donnée par:

 \| \vec{a} \| = g.sin(\Theta)

Modèle géométrique pour robots mobiles à roues différentielles

Dans cet article, le modèle géomètrique est une transformation mathèmatique dont les entrées sont les vitesses angulaires des roues (généralement mesurées avec des codeurs) et la sortie est la pose (position et orientation) du robot mobile dans son espace de travail.

Définition du problème

nous nous intéresserons ici aux robots à roues différentielles. Ce type de robot est constitué de deux roues alignées sur le même axe. Ci-dessous, se trouve une illustration de Rat-Courci, un petit robot à roues différentielles conçu pour le concours Micromouse:

Rat-Courci

Le diamètre des roues est donné par D=2.rr est le rayon. La distance entre le centre du robot et les roues est donné par l, la distance entre les roues est alors donnée par 2.l conformément à l’illustration suivante:

Dimensions

Nous supposerons les paramètres suivants connus:


  • r est le rayon des roues

  • l la distance entre le centre du robot et les roues

  • \omega_l et \omega_r sont respectivement les vitesses angulaires instantanées des roues gauche et droite

Geometric_Model

Notre but est de calculer la pose du robot définie selon la figure ci-dessus:


  • x et y sont les coordonnées cartésiennes du robot

  • \psi est l’orientation (position angulaire) du robot

Calcul des déplacements élémentaires

Pour commencer, calculons la vitesse linéaire de chaque roue:

\begin{array}{r c l} v_l &=& r.\omega_l \\ v_r &=& r.\omega_r\end{array}

La vitesse moyenne du robot est alors donnée par:

 v_{robot}=\frac {v_l + v_r} {2}

La vitesse du robot peut être projetée le long des axes x et y:

\begin{array}{r c l} \Delta_x &=& v_{robot}.cos(\psi)&=&\frac {r}{2} ( \omega_l.cos(\psi) + \omega_r.cos(\psi))\\ \Delta_y &=& v_{robot}.sin(\psi)&=&\frac {r}{2} ( \omega_l.sin(\psi) + \omega_r.sin(\psi))\end{array}

La vitesse angulaire du robot est calculée par la différence des vitesses linéaires des roues:

 2.l.\Delta_{\Psi}=r.\omega_r - r.\omega_l

L’équation précédente peut être reformulée:

 \Delta_{\Psi}=\frac {r.\omega_r - r.\omega_l} {2.l}

Le déplacement élémentaire du robot est donnée par la relation suivante:

\left[ \begin{matrix} \Delta_x \\ \Delta_y \\ \Delta_{\Psi} \end{matrix} \right]=\frac{r}{2}.\left[ \begin{matrix} cos(\psi) & cos(\psi) \\sin(\psi) & sin(\psi) \\\frac{1}{l} & \frac{-1}{l}\end{matrix} \right].\left[ \begin{matrix} \omega_r \\ \omega_l\end{matrix} \right]

Position absolue

La position absolue peut être calculée grâce aux équations suivantes:

\begin{array}{r c l}
x_{i}&=&x_{i-1}+\Delta_x \\
y_{i}&=&y_{i-1}+\Delta_y \\
\Psi_{i}&=&Psi_{i-1}+\Delta_{\Psi}
\end{array}

où:


  • x_{i} et y_{i} sont les coordonnées cartésiennes du robot à l’instant i

  • \Psi_{i} est l’orientation du robot à l’instant i

Bien sûr, ce modèle a quelques limitations. Le résultat est fortement dépendant de la précision de la mécanique du robot (ajustements, diamètre des roues, mesures …). Nous supposons ici qu’il n’y a pas de glissement, ce qui n’est pas vrai en pratique. Nous supposons également que la fréquence d’échantillonnage est suffisamment rapide pour garantir que \Delta_x, \Delta_y et \Delta_\Psi pourront être considérés comme des déplacements élémentaires.

Asservissement PI pour un système du premier ordre

Introduction

Le but de ce post est d’expliquer et de démontrer comment calculer un correcteur PI (proportionel-intégral) pour un système du premier ordre. Considérons le système à asservir avec pour fonction de transfert G, le système en boucle fermé est donné par le schéma suivant:

ClosedLoopControl

Fonction de transfert en boucle fermée

La fonction de transfert du stystème est donnée par:

 \frac{y}{y_c} = \frac {CG}{1+CG}

comme G est modélisé par un système du premier ordre, sa fonction de transfert est donnée par:

 G=\frac{b}{z-a} = \frac{b} { z-e^{-\Delta/\tau} }

\Delta est la période d’échantillonage et \tau la constante de temps du système en boucle ouverte.

C est le correcteur PI, sont équation est donnée par:

 C=K . \frac{z-a}{z-1}

La fonction de tranfert du système en boucle fermée devient:

 \frac{y}{y_c} = \frac { K \frac{z-a}{z-1} \frac{b}{z-a} }{1+ K \frac{z-a}{z-1} \frac{b}{z-a}}

L’équation précédente peut être simplifiée:

 \frac{y}{y_c} = \frac { K \frac{b}{z-1} }{1+ K \frac{b}{z-1} }

La nouvelle fonction de transfert est donnée par:

 \frac{y}{y_c} = \frac { Kb }{ z -1 + Kb }

Gain statique du système en boucle fermée

Considérons la réponse du système en boucle fermée à une entrée de type échelon unitaire (\frac{z}{z-1}):

 y(z) = \frac { zKb }{ (z -1 + Kb)(z-1) }

D’après le théorème de la valeur finale (transformée en z), le gain statique du système est donné par:

 \lim\limits_{z \to 1} (z-1).y(z) = \lim\limits_{z \to 1} \frac { zKb(z-1) }{ (z -1 + Kb)(z-1) } = \lim\limits_{z \to 1} \frac { zKb }{ (z -1 + Kb) } = 1

Comme le gain statique du système est équal à 1, l’erreur statique est nulle.

Constante de temps du système en boucle fermée

Le système en boucle fermée est aussi un premier ordre :

 \frac{y}{y_c} = \frac { Kb }{ z -1 + Kb } = \frac { Kb }{ z - e^{-\Delta/\tau_c} }

\Delta est la période d’échantillonage et \tau_c la constante de temps du système en boucle fermée. Il est à noter que \tau_c peut être inférieur à \tau (la constante de temps du système en boucle ouverte). Si \tau_c<\tau le système est plus vif, (mais consomme plus d’énergie). En pratique, \tau_c=\tau/2 est un bon compromis. D’après l’équation précédente :

 1-Kb = e^{-\Delta/\tau_c}
et :
 K= \frac {1-e^{-\Delta/\tau_c}} {b}
Pour obtenir le même temps de réponse en boucle ouverte et en boucle fermée, l’équation précédente devient:
 K= \frac {1-a} {b}

Stabilité

Le système est stable si tous ses pôles sont situés à l’intérieur du cercle unité. Ici, comme le système est du premier ordre, il n’y a qu’un seul pôle : 1-Kb. Le système est stable si:

 -1<1-Kb<1
Cette équation peut être reformulée :
 0<kb<2
et=”” :=””
="" 0<k<\frac{2}{b}
=”” il=”” est=”” à=”” noter=”” que=”” si=”” ="" k="" calculé="" depuis="" \tau_c="" (k=”\frac” {1-e^{-\delta=”” \tau_c}}=”” {b}="" ),="" le="" terme="" e^{-\delta=”” \tau_c}="" inclus="" dans="" l[0,1[="" système="" nécessairement="" stable="" car="" en="" découle="" 0<kb\le1.="" <h2="">Domaine échantillonné </kb<2>

La fonction de transfert du correcteur exprimée dans le domaine échantillonné est donnée par:

 \frac{u(z)}{\epsilon(z)} = K . \frac{z-a}{z-1}

 (z-1)u(z) = K(z-a)\epsilon(z)

 z.u(z) - u(z) = K.z.\epsilon(z) -K.a.\epsilon(z)

 z.u(z) = K.z.\epsilon(z) - K.a.\epsilon(z) + u(z)

Exprimons maintenant l’équation précédente dans le domaine discret:

 u_{n+1}= K\epsilon_{n+1} - K.a.\epsilon_n + u_{n}

ou :

 u_{n}= K\epsilon_{n} - K.a.\epsilon_{n-1} + u_{n-1}

Vidéo

Téléchargement

Remerciements

Je tiens à remercier Laurent Hardouin de l’Université d’Angers pour son aide et ses explications.

Convertir des tours par minute [ rpm ] en radians par seconde [ rad/s ], ou l’inverse.

Conversion en ligne

Formules

Explication

rpm signifie rotation par minute (revolutions per minute en anglais). Le but de ce post est de convertir N (exprimé en rpm) vers \omega (exprimé en rad.s^{-1}). Si le système réalise N tours en une minute, \frac {N}{60} tours seront faits en une seconde. Comme un tour est égal à 2\pi radians, la conversion peut être calculée grâce à la formule suivante:

 \omega[rad.s^{-1}] = \frac {2\pi}{60}.N[rpm]

et vice versa:

 N[rpm] = \frac {60}{2\pi}.\omega[rad.s^{-1}]

Pour plus d’options, rendez-vous sur Calculatrix.

 

Boucle ouverte / boucle fermée

Boucle ouverte

Considérons le système suivant en boucle ouverte:

OpenLoop

La fonction de transfert du système est donnée par :

 \frac {y}{u} = G

Boucle fermée

Considérons maintenant le système en boucle fermée:

ClosedLoop

L’érreur  \epsilon est définie par la différence entre la consigne (valeur désirée) et la sortie du système (la valeur réelle) :

 \epsilon = y_c - y

La sortie du système est donnée par :

 y=G.u=G.\epsilon

En replaçant \epsilon dans l’équation précédente, nous obtenons:

 y=G.(y_c - y) = G.y_c - G.y

Cette équation peut être reformulée de façon à obtenir la fonction de transfert suivante :

 \frac{y}{y_c} = \frac {G}{1+G}

Boucle fermée avec correcteur

Considérons maintenant l’ajout d’un correcteur :

ClosedLoopControl

Nous pouvons en déduire la fonction de transfert suivante:

 \frac{y}{y_c} = \frac {CG}{1+CG}

Collision élastique

Cet article traite du calcul de la direction et de la vitesse de corps circulaires suite à une collision élastique.

Nous supposerons qu’il y a conservation de l’énergie cinétique au moment de la collision. Considérons deux corps identifés grâce aux indices 1 et 2 et définissons :

  • m_1, m_2 les masse,
  • \vec{u_1}, \vec{u_2} les vitesses avant collision,
  • \vec{v_1}, \vec{v_2} les vitesses après collision,
  • (x_1,y_1) et (x_2,y_2) les coordonnées des centres des corps au moment du choc.

CollisionGeneral

L’objectif est de calculer \vec{v_1} et \vec{v_2} en fonction de m_1, \vec{u_1}, m_2, \vec{u_2}, x_1, y_1, x_2 et y_2

Décomposition de la vitesse

Détaillons la collision:

Collision

Au moment de la collision, le vecteur vitesse peut être décomposé: une partie est transmise à l’autre corps et le reste est conservé. Dans l’illustration ci-dessus, la vitesse (\vec{u_1}) du corps 1 est décomposée en deux vecteurs:

  • une partie est transmise au corps 2 (\vec{u_{12}})
  • une partie est conservée par le corps 1 (\vec{u_{11}})

La partie transmise est la projection le long de l’axe passant par les centres des corps. En s’appuyant sur l’illustration précédente, nous pouvons écrire:

 \|\vec{u_{12}}\|=\|\vec{u_1}\|.cos(\gamma)

Comme \gamma=\beta-\alpha, la relation précédente devient:
 \|\vec{u_{12}}\|=\|\vec{u_1}\|.cos(\beta-\alpha)

avec \alpha et \beta définis par:

 \begin{array}{r c l}\alpha &=& atan2(y_2-y_1,x_2-x_1) \\\beta &=& atan2(y_{u_1},x_{u_1})\end{array}

En conclusion:

 \begin{array}{r c l}\gamma_1 &=& atan2(y_{u_1},x_{u_1}) - atan2(y_2-y_1,x_2-x_1) \\\|\vec{u_{12}}\| &=& \|\vec{u_1}\|.cos(\gamma_1)  \\\|\vec{u_{11}}\| &=& \|\vec{u_1}\|.sin(\gamma_1) \\\gamma_2 &=& atan2(y_{u_2},x_{u_2}) - atan2(y_1-y_2,x_1-x_2) \\\|\vec{u_{21}}\| &=& \|\vec{u_2}\|.cos(\gamma_2)  \\\|\vec{u_{22}}\| &=& \|\vec{u_2}\|.sin(\gamma_2) \end{array}

et

 \begin{array}{r c l}\alpha_1 &=& atan2(y_2-y_1,x_2-x_1) \\\vec{u_{12}} &=& \|\vec{u_{12}}\| \left( \begin{array}{r c l}  cos(\alpha_1) \\ sin(\alpha_1) \end{array} \right) \\\vec{u_{11}} &=& \|\vec{u_{11}}\|  \left( \begin{array}{r c l}  -sin(\alpha_1) \\ cos(\alpha_1) \end{array} \right)  \\\alpha_2 &=& atan2(y_1-y_2,x_1-x_2) \\\vec{u_{21}} &=& \|\vec{u_{21}}\| \left( \begin{array}{r c l}  cos(\alpha_2) \\ sin(\alpha_2) \end{array} \right) \\\vec{u_{22}} &=& \|\vec{u_{22}}\|  \left( \begin{array}{r c l}  -sin(\alpha_2) \\ cos(\alpha_2) \end{array} \right)  \end{array}

Vitesse

Intéressons nous maintenant au calcul de la norme des vitesses partielles après collision pour chaque corps. Ce problème peut se résumer à une collision frontale où:

  • \vec{u_{12}} et \vec{u_{21}} sont les vitesses avant collision,
  • \vec{v_{12}} et \vec{v_{21}} sont les vitesses après collision.

Choc

Conservation de l’énergie cinétique

 \frac{1}{2}m_1\|\vec{u_{12}}\|^2 + \frac{1}{2}m_2\|\vec{u_{21}}\|^2 = \frac{1}{2}m_1\|\vec{v_{12}}\|^2 + \frac{1}{2}m_2\|\vec{v_{21}}\|^2

Peut être reformulé de la façon suivante:
 m_1(\|\vec{u_{12}}\|^2 - \|\vec{v_{12}}\|^2) = m_2(\|\vec{v_{21}}\|^2 - \|\vec{u_{21}}\|^2)

Conservation de la quantité de mouvement

 m_1\vec{u_{12}} + m_2\vec{u_{21}} = m_1\vec{v_{12}} +m_2\vec{v_{21}}

Peut être reformulé de la façon suivante:
 m_1\|\vec{u_{12}}\|+m_2\|\vec{u_{21}}\|=m_1\|\vec{v_{12}}\|+m_2\|\vec{v_{21}}\|

et :
 m_1(\|\vec{u_{12}}\| - \|\vec{v_{12}}\|) = m_2(\|\vec{v_{21}}\|-\|\vec{u_{21}}\|)

Résolution du système d’équations

Le système global est donné par:

 \left \{ \begin{array}{r c l}m_1(\|\vec{u_{12}}\|^2 &-& \|\vec{v_{12}}\|^2) & = & m_2(\|\vec{v_{21}}\|^2 &-&  \|\vec{u_{21}}\|^2) \\m_1(\|\vec{u_{12}}\| &-& \|\vec{v_{12}}\|) & = & m_2(\|\vec{v_{21}}\| &-& \|\vec{u_{21}}\|)\end{array} \right .

Le système peut être réécrit:

 \left \{ \begin{array}{r c l}m_1( \|\vec{u_{12}}\| + \|\vec{v_{12}}\|)( \|\vec{u_{12}}\| - \|\vec{v_{12}}\|) & = & m_2(\|\vec{v_{21}}\| -  \|\vec{u_{21}}\|)(\|\vec{v_{21}}\| +  \|\vec{u_{21}}\|) \\m_1(\|\vec{u_{12}}\| - \|\vec{v_1}\|) & = & m_2(\|\vec{v_{21}}\| - \|\vec{u_{21}}\|)\end{array} \right .

En divisant la première équation par la seconde, on obtient:

 \|\vec{u_{12}}\| + \|\vec{v_{12}}\| = \|\vec{u_{21}}\| +  \|\vec{v_{21}}\|

Nous obtenons le nouveau système suivant:

 \left \{ \begin{array}{r c l}\|\vec{u_{12}}\| + \|\vec{v_{12}}\| &=& \|\vec{u_{21}}\| + \|\vec{v_{21}}\| \\m_1(\|\vec{u_{12}}\| - \|\vec{v_{12}}\|) &=& m_2(\|\vec{v_{21}}\| - \|\vec{u_{21}}\|)\end{array} \right .

Multiplions la première équation par m_1:

 \left \{ \begin{array}{r c l}m_1\|\vec{u_{12}}\| &+& m_1\|\vec{v_{12}}\| &=& m_1\|\vec{u_{21}}\| &+& m_1\|\vec{v_{21}}\| \\m_1\|\vec{u_{12}}\| &-& m_1\|\vec{v_{12}}\| &=& m_2\|\vec{u_{21}}\| &-& m_2\|\vec{v_{21}}\|\end{array} \right .

L’addition de la première équation par la seconde nous donne:

 2m_1\|\vec{u_{12}}\| = (m_1-m_2)\|\vec{u_{21}}\| + (m_1+m_2)\|\vec{v_{21}}\| \\

Les vitesses \|\vec{v_{12}}\| et \|\vec{v_{21}}\| après le choc peuvent maintenant être déduites:

 \left \{ \begin{array}{r c l}\|\vec{v_{12}}\| = \frac{ 2m_2\|\vec{u_{21}}\| + (m_1-m_2)\|\vec{u_{12}}\|}{m_1+m_2}  \\\|\vec{v_{21}}\| = \frac{ 2m_1\|\vec{u_{12}}\| + (m_2-m_1)\|\vec{u_{21}}\|}{m_1+m_2}  \end{array} \right .

Prenons maintenant en compte le fait que que le vecteur \vec{u_{21}} a une direction opposée par rapport au vecteur \vec{u_{12}}. L’équation précédente devient:

 \left \{ \begin{array}{r c l}\|\vec{v_{12}}\| = \frac{  (m_1-m_2)\|\vec{u_{12}}\| - 2m_2\|\vec{u_{21}}\| }{m_1+m_2}  \\\|\vec{v_{21}}\| = \frac{  (m_1-m_2)\|\vec{u_{21}}\| + 2m_1\|\vec{u_{12}}\| }{m_1+m_2}  \end{array} \right .

Synthèse

Le vecteur \vec{v_1} peut maintenant être calculé:

 \vec{v_1}=\vec{u_{11}}+\vec{v_{12}} = \|\vec{u_{11}}\| \left( \begin{array}{r c l} -sin(\alpha_1) \\ cos(\alpha_1) \end{array} \right) + \|\vec{v_{12}}\| \left( \begin{array}{r c l} cos(\alpha_1) \\ sin(\alpha_1) \end{array} \right)

En prenant en compte la direction opposée de \vec{v_{21}} nous pouvons calculer \vec{v_2}:

 \vec{v_2}=\vec{u_{22}}+\vec{v_{21}} = \|\vec{u_{22}}\| \left( \begin{array}{r c l} -sin(\alpha_2) \\ cos(\alpha_2) \end{array} \right) - \|\vec{v_{21}}\| \left( \begin{array}{r c l} cos(\alpha_2) \\ sin(\alpha_2) \end{array} \right)

Résumé

1 – Calcul des angles:

 \begin{array}{r c l}\alpha_1 &=& atan2(y_2-y_1,x_2-x_1) \\\beta_1 &=& atan2(y_{u_1},x_{u_1}) \\\gamma_1 &=&\beta_1-\alpha_1 \\\alpha_2 &=& atan2(y_1-y_2,x_1-x_2) \\\beta_2 &=& atan2(y_{u_2},x_{u_2}) \\\gamma_2 &=&\beta_2-\alpha_2\end{array}

2 – Calcul de la norme des vecteurs après décomposition:

 \begin{array}{r c l}\|\vec{u_{12}}\| &=& \|\vec{u_1}\|.cos(\gamma_1)  \\\|\vec{u_{11}}\| &=& \|\vec{u_1}\|.sin(\gamma_1)  \\\|\vec{u_{21}}\| &=& \|\vec{u_2}\|.cos(\gamma_2)  \\\|\vec{u_{22}}\| &=& \|\vec{u_2}\|.sin(\gamma_2) \end{array}

3 – Calcul de la norme des sous vecteurs \|\vec{v_{12}}\| et \|\vec{v_{21}}\| après collision:

 \left \{ \begin{array}{r c l}\|\vec{v_{12}}\| = \frac{  (m_1-m_2)\|\vec{u_{12}}\| - 2m_2\|\vec{u_{21}}\| }{m_1+m_2}  \\\|\vec{v_{21}}\| = \frac{  (m_1-m_2)\|\vec{u_{21}}\| + 2m_1\|\vec{u_{12}}\| }{m_1+m_2}  \end{array} \right .

4 – Enfin, calcul de la vitesse \vec{v_1} pour le corps 1:

 \vec{v_1}=\|\vec{u_{11}}\| \left( \begin{array}{r c l} -sin(\alpha) \\ cos(\alpha) \end{array} \right) + \|\vec{v_{12}}\| \left( \begin{array}{r c l} cos(\alpha) \\ sin(\alpha) \end{array} \right)

5 – \vec{v_2} peut être calculé de la même manière:
 \vec{v_2}=\|\vec{u_{22}}\| \left( \begin{array}{r c l} -sin(\alpha_2) \\ cos(\alpha_2) \end{array} \right) - \|\vec{v_{21}}\| \left( \begin{array}{r c l} cos(\alpha_2) \\ sin(\alpha_2) \end{array} \right)

Téléchargmeent

Remerciements

Je tiens à remercier Jean-Pierre Pecqueur de l’Université d’Angers pour son aide, ses explications et sa patience.

Splines Catmull-Rom

La méthode de Catmull-Rom splines permet d’approximer une série de points (appelés points de contrôle) avec une courbe continue qui est définie par morceaux. Une des propriétés de cette méthode est qu’elle permet de passer par tous les points de contrôle.

Mise en équations

Deux points sont nécessaires de chaque côté de la portion que l’on souhaite interpoller. En d’autres termes, il faut disposer des points P_{i-1} et P_{i+2} pour calculer la spline entre les points P_i et P_{i+1}.

SplineCatmullRom

Considérons les points P_{i-1}, P_{i}, P_{i+1} et P_{i+2}. Les coordonnées du point P situé entre P_i et P_{i+1} sont calculées de la façon suivante:
$! P = \frac{1}{2} . 
\left[ \begin{matrix} 1 & t & t^2 & t^3 \end{matrix} \right].
\left[ \begin{matrix} 
0 & 2 & 0 & 0 \\
-1 & 0 & 1 & 0 \\
2 & -5 & 4 & -1 \\
-1 & 3 & -3 & 1
\end{matrix} \right].
\left[ \begin{matrix} 
P_{i-1} & P_{i} & P_{i+1} & P_{i+2}
\end{matrix} \right]^\top
$

Cas général : tension

L’équation précédente est un cas particulier de la généralisation donnée par la matrice suivante:
$! P = 
\left[ \begin{matrix} 1 & t & t^2 & t^3 \end{matrix} \right].
\left[ \begin{matrix} 
0 & 1 & 0 & 0 \\
-\tau & 0 & \tau & 0 \\
2.\tau & \tau-3 & 3-2\tau & -\tau \\
-\tau & 2-\tau & \tau-2 & \tau
\end{matrix} \right].
\left[ \begin{matrix} 
P_{i-1} & P_{i} & P_{i+1} & P_{i+2}
\end{matrix} \right]^\top
$
Le paramètre \tau modifie la tension de la courbe. La figure suivante illustre l’influence du paramètre \tau sur la courbe. \tau=\frac{1}{2} est une valeur couramment utilisée pour un résultat générique (comme dans le cas particulier présenté précédemment).
Tau_0 Tau_0_25 Tau_0_5
$\tau=0$
$\tau=0.25$
$\tau=0.5$
Tau_0_75 Tau_1 Tau_2
$\tau=0.75$
$\tau=1$
$\tau=2$

Derivation

Etant donné que la courbe est de classe C^1 il est possible de déterminer la dérivée pour toutes les valeurs de t. De plus, comme la courbe est définie par un polynôme, le calcul de la dérivée en un point est relativement trivial:

$! P = 
\left[ \begin{matrix} 0 & 1 & 2.t & 3.t^2 \end{matrix} \right].
\left[ \begin{matrix} 
0 & 1 & 0 & 0 \\
-\tau & 0 & \tau & 0 \\
2.\tau & \tau-3 & 3-2\tau & -\tau \\
-\tau & 2-\tau & \tau-2 & \tau
\end{matrix} \right].
\left[ \begin{matrix} 
P_{i-1} & P_{i} & P_{i+1} & P_{i+2}
\end{matrix} \right]^\top
$

example_derivative

Propriétés

La courbe passe par tous les points de contrôle.
La courbe est de classe C^1.
La courbe n’est pas de classe C^2.
La courbe n’est pas incluse dans l’enveloppe convexe des points de contrôle.

Exemples

example1 example2
exemple3 exemple4
Spline3D

Download

Tester si quatre points sont coplanaires

Le but de cet article est de vérifier si 4 points sont coplanaires, c’est à dire qu’ils appartiennent au même plan. Considérons quatre points P_1, P_2, P_3 et P_4 définis dans \mathbb{R}^3. La question peut être reformulée de la façon suivante : “est-ce que le point P_4 appartient au plan défini pas les points P1, P_2 et P_3“. Commençons par calculer le vecteur normal au plan défini par les points P_1, P_2 et P_3:

\vec{n_1}=\vec{P_1P_2} \times \vec{P_1P_3}

Calculons maintenant le vecteur normal au plan défini par les points P_1, P_2 et P_4:

\vec{n_2}=\vec{P_1P_2} \times \vec{P_1P_4}

Si les quatre points appartiennent au plan, les vecteurs \vec{n_1} et \vec{n_2} sont colinéaires et cela peut être vérifié grâce au produit scalaire des vecteurs normaux:

 \vec{n_1} \cdot \vec{n_2} =0

La relation peut être reformulée:

 (\vec{P_1P_2} \times \vec{P_1P_3}) \cdot (\vec{P_1P_2} \times \vec{P_1P_4}) =0

Puis simplifiée:

 \vec{P_1P_2} \cdot (\vec{P_1P_3} \times \vec{P_1P_4}) =0

Les quatres points sont coplanaires, si et seulement si,  \vec{P_1P_2} \cdot (\vec{P_1P_3} \times \vec{P_1P_4}) =0 .

Segments tangents à deux cercles

Introduction

Cet article traite du calcul des coordonnées des points d’intersection des tangentes à deux cercles. Comme le montre la figure suivante, quatre configurations peuvent exister dans le cas général:

  • R_A et P_A sont respectivement le rayon et le centre du premier cercle.
  • R_B et P_B sont respectivement le rayon et le centre du deuxième cercle.
  • P_1 est le point de contact de la tangente sur le premier cercle.
  • P_2 est le point de contact de la tangente sur le deuxième cercle.

CirclesTangents_001

Mise en équation

Pour commencer, considérons le fait que chaque point appartient au cercle:

\left \{ \begin{array}{r c l}(x_1 - x_A)^2 + (y_1 - y_A)^2 = {R_A}^2 \\(x_2 - x_B)^2 + (y_2 - y_B)^2 = {R_B}^2\end{array} \right .

Considérons maintenant le fait que chaque segment tangent est perpendiculaire au rayon:

\left \{ \begin{array}{r c l}(x_1 - x_2)^2 + (y_1 - y_2)^2 + {R_A}^2 = (x_2 - x_A)^2 + (y_2 - y_A)^2 \\(x_1 - x_2)^2 + (y_1 - y_2)^2 + {R_B}^2 = (x_1 - x_B)^2 + (y_1 - y_B)^2 \end{array} \right .

Il devient alors possible de résoudre ces quatre équations afin de déterminer les quatre inconnues. Malheureusement, le système n’est pas linéaire et la résolution est complexe.

Configuration de Thales

En revanche, nous pouvons tirer avantageusement profit des configurations de Thales qui nous permettent de calculer facilement la longueur \left | P_1 P_2 \right |.

Première configuration

Dans cette configuration, le point U est ajouté sur le rayon C_B de façon à ce que  \left | UP_B \right | = R_B - R_A

First Thales configuration

Le triangle \widehat {P_A U P_B} est rectangle et \left | P_AU \right |^2 + \left | P_BU \right |^2 = \left | P_AP_B \right |^2. En s’appuyant sur ce triangle, nous pouvons déduire que :

\left | P_1P_2 \right | = \sqrt { \left | P_AP_B \right |^2 - (R_A - R_B)^2 }

De l’équation précédente, nous pouvons déduire que la première configuration n’existe que si \left | P_AP_B \right |^2 \ge (R_A - R_B)^2 , c’est à dire si aucun des cercles n’est intégralement inclus dans l’autre.

Deuxième configuration

Dans cette nouvelle configuration, les points A et P_1 sont ajoutés de façon à ce que \left | P_AP_B \right | = \left | MA and \left | P_1P_2 \right | = \left | MP_1. Notez que, d’après Thales : \left | P_1

Second Thales configuraiton

Comme pour la première configuration \widehat {M P_1 est un triangle rectangle.

\left | MP_1
\left | P_1P_2 \right |^2 + (R_A + R_B)^2 = \left | P_AP_B \right |^2

Il devient facile de déduire:

\left | P_1P_2 \right | = \sqrt { \left | P_AP_B \right |^2 - (R_A + R_B)^2 }

De l’équation précédente, nous pouvons déduire que la seconde configuration n’existe que si \left | P_AP_B \right |^2 \ge (R_A + R_B)^2 , c’est à dire aucun des cercles n’est intégralement inclus dans l’autre.

Simplification des équations

Une fois que \left | P_1P_2 \right | est connu, les équations peuvent être reformulées. Considérons L équal à\left | P_1P_2 \right |, les équations deviennent::

\left \{ \begin{array}{ll}(x_1 - x_A)^2 + (y_1 - y_A)^2 = {R_A}^2 \\L^2 + {R_B}^2 = (x_1 - x_B)^2 + (y_1 - y_B)^2 \end{array} \right . \\\left \{ \begin{array}{ll}(x_2 - x_B)^2 + (y_2 - y_B)^2 = {R_B}^2 \\L^2 + {R_A}^2 = (x_2 - x_A)^2 + (y_2 - y_A)^2\end{array} \right .

Nous disposons maintenant de deux systèmes indépendants non linéaires à résoudre, étant donné la symétrie du problème, la résolution d’un système nous permet d’obtenir la solution générale.

Résolution des équations

Comme les systèmes sont équivalents, nous allons nous intéresser au premier:

\left \{ \begin{array}{ll}(x_1 - x_A)^2 + (y_1 - y_A)^2 = {R_A}^2 \\(x_1 - x_B)^2 + (y_1 - y_B)^2 = L^2 + {R_B}^2\end{array} \right .

Il est évident que la solution géométrique est l’intersection de deux cercles de centres P_A et P_B avec des rayons respectifs de R_A et \sqrt{L^2+{R_B}^2}.

Les coordonnées de P_1 sont données par :

\left \{ \begin{array}{ll}x_1= \frac{x_A+x_B}{2} + \frac{(x_B-x_A)({R_A}^2-{R_1}^2)}{2D^2} \pm 2\frac{y_A-y_B}{D^2}\sigma_1  \\y_1= \frac{y_A+y_B}{2} + \frac{(y_B-y_A)({R_A}^2-{R_1}^2)}{2D^2} \pm 2\frac{x_A-x_B}{D^2}\sigma_1 \end{array} \right .

avec

\begin{array}{ll}D = \sqrt{ (x_B-x_A)^2 + (y_B-y_A)^2 } \\L = \sqrt { D^2 - (R_A \pm R_B)^2 } \\R_1= \sqrt{L^2+{R_B}^2} \\\sigma_1=\frac{1}{4}\sqrt{ (D+R_A+R_1)(D+R_A-R_1)(D-R_A+R_1)(-D+R_A+R_1) }\end{array} .

Nous pouvons, de la même façon déterminer les coordonnées de P_2:

\left \{ \begin{array}{ll}x_2= \frac{x_B+x_A}{2} + \frac{(x_A-x_B)({R_B}^2-{R_2}^2)}{2D^2} \pm 2\frac{y_B-y_A}{D^2}\sigma_2  \\y_2= \frac{y_B+y_A}{2} + \frac{(y_A-y_B)({R_B}^2-{R_2}^2)}{2D^2} \pm 2\frac{x_B-x_A}{D^2}\sigma_2 \end{array} \right .

avec

\begin{array}{ll}D = \sqrt{ (x_B-x_A)^2 + (y_B-y_A)^2 } \\L = \sqrt { D^2 - (R_B \pm R_A)^2 } \\R_2= \sqrt{L^2+{R_A}^2} \\\sigma_2=\frac{1}{4}\sqrt{ (D+R_B+R_2)(D+R_B-R_2)(D-R_B+R_2)(-D+R_B+R_2) }\end{array} .

Un test rapide sous Matlab confirme les résultats :

Circles & Tangents

Code source Matlab

Tester si trois points sont alignés

Considérons trois points A, B et C. Un moyen efficace de savoir si les trois points sont alignés est de calculer le produit vectoriel de \vec{AB} et \vec{AC}. Si \vec{AB} \times \vec{AC} retourne un vecteur nul, soit les trois points sont alignés, soit deux points ou plus sont coincidents.

Code source C++


/*!
* \brief rOc_segment::isPointAligned check if a point is aligned with the segment
* \param P point to test
* \return ROC_SEGMENT_INTERSEC_NONE if the point doesn’t lay with the segment
* ROC_SEGMENT_INTERSEC_EXTREMITY_P1 if the point is merged with P1
* ROC_SEGMENT_INTERSEC_EXTREMITY_P2 if the point is merged with P2
* ROC_SEGMENT_INTERSEC_CROSS if the point belongs to the segment (extremity no included)
*/
bool rOc_segment::isPointAligned(rOc_point P)
{
// Compute vectors AB and AC
rOc_vector AB=this->vector();
rOc_vector AC(this->point1(),P);

// Check if the cross product is a null vector
if (AB.cross(AC).isNull()) return true;
return false;
}

Produit scalaire (dot product)

Le produit scalaire de deux vecteurs est le produit des longueurs des deux vecteurs par le cosinus de l’angle formé par les vecteurs. Le produit scalaire des vecteurs \vec{V} et \vec{U} peut être calculé grâce à la formule suivante:
 \vec{V} \cdot \vec{U} = V_x.U_x + V_y.U_y + V_z.U_z = \| \vec{V} \|. \| \vec{U} \| .cos (\theta)

\theta est l’angle formé par les vecteurs \vec{V} et \vec{U}.

Propriétés

Si \vec{V} et \vec{U} sont hortogonaux, \vec{V} \cdot \vec{U} est égal à zéro.
Si \vec{V} est nul, \vec{V} \cdot \vec{U} est égal à zéro.
Si \vec{U} est nul, \vec{V} \cdot \vec{U} est égal à zéro.
\vec{V} \cdot \vec{V} = \| \vec{V} \| ^2
\vec{V} \cdot \vec{U} = \vec{U} \cdot \vec{V}
\vec{V} \cdot (-\vec{U}) = (-\vec{V}) \cdot \vec{U} = - ( \vec{V} \cdot \vec{U} )

Code source C++

/*!
 * \brief   Compute the dot product of two vectors (this . V)
 *          The current vector is the first operand
 * \param   V is the second operand
 * \return  the dot product between the current vector and V
 */
inline double rOc_vector::dot(const rOc_vector V)
{
    return this->x()*V.x() + this->y()*V.y() + this->z()*V.z();
}

Tester si deux segments (ou vecteurs) sont parallèles

Pour vérifier si deux segments S_A et S_B sont parallèles, calculer le vecteur associé à chaque segment et et vérifier que le produit vectoriel est un vecteur nul

ParalellSegments

Calculer les vecteurs \vec{V_A} et \vec{V_B} :

 \vec{V_A}=\vec{P_1P_2}

 \vec{V_B}=\vec{P_3P_4}

Ensuite calculer le produit vectoriel :

 \vec{C} = \vec{V_A} \times \vec{V_B}

\vec{V} est nul si S_A est nul ou si S_B est nul ou si S_A et S_B sont parallèles.

Source code C++


/*!
* \brief rOc_segment::isParallel check if current segment and S are parallel
* A null segment is necessarily considered as parallel
* \param S is the segment to check with the current one
* \return true the segments are parallel or at least one of the segment is null
* false the segments are non null and not parallel
*/
bool rOc_segment::isParallel(rOc_segment S)
{
// Extract main vector
rOc_vector VA=this->vector();
rOc_vector VB=S.vector();

// If the dot product is a null vector, segments are parallel (or at least one is null)
return VA.cross(VB).isNull();
}

Produit vectoriel (cross product)

Le produit vectoriel de deux vecteurs est un vecteur perpendiculaire au plan formé par les deux vecteurs. Le produit vectoriel de \vec{V} et \vec{U} peut être calculé grâce à la formule suivante:
 \vec{V} \times \vec{U} = \left (\begin{matrix}  V_y.U_z - V_z.U_y \\  V_z.U_x - V_x.U_z \\  V_x.U_y - V_y.U_x \end{matrix}\right )

Propriétés

Si \vec{V} et \vec{U} sont collinéaires, \vec{V} \times \vec{U} est un vecteur nul.
Si \vec{V} est nul, \vec{V} \times \vec{U} est un vecteur nul.
Si \vec{U} est nul, \vec{V} \times \vec{U} est un vecteur nul.
\vec{V} \times \vec{U} est normal au plan formé par les vecteurs \vec{V} et \vec{U}.
\vec{V} \times \vec{U}=-(\vec{U} \times \vec{V}) = (-\vec{U}) \times \vec{V}

Code source C++

/*!
 * \brief   Compute the cross product of two vectors (this x V)
 *          The current vector is the first operand
 * \param   V is the second operand
 * \return  a vector = the cross product of the current vector by V
 */
inline rOc_vector rOc_vector::cross(const rOc_vector V)
{
    rOc_vector Res;
    Res.x()=this->y()*V.z() - this->z()*V.y();
    Res.y()=this->z()*V.x() - this->x()*V.z();
    Res.z()=this->x()*V.y() - this->y()*V.x();
    return Res;
}

Vérifier qu’un point appartient à un segment

Considérons un segment S défini par deux points A et B. Le but ici est de savoir si un troisième point C appartient au segment S.

Overview

Cette vérification est faite en deux étapes.

Est-ce que A, B et C sont alignés ?

La première étape consiste à vérifier si A, B et C sont alignés, i.e. si les vecteurs \vec{AB} et \vec{AC} sont colinéaires. Cela est facilement testé en calculant le produit vectoriel suivant:

\vec{AB} \times \vec{AC}=0

Si le produit vectoriel de \vec{AB} et \vec{AC} est égal à zéro, cela implique que les vecteurs sont colinéaires ou que les points A et B ou A et C sont coincidents. Si le produit vectoriel est différent de zéro, le point n’appartient pas au segment.

Est-ce que C se trouve entre A et B ?

En supposant que les points A, B and C sont alignés, il ne nous reste plus qu’à tester si le point C est situé entre A et B. Cela peut être vérifié en testant si le produit scalaire des vecteurs \vec{AB} et \vec{AC} est positif et inférieur au produit scalaire de \vec{AB} et \vec{AB}. Calculer K_{AC} et K_{AB} selon la formule suivante:

 K_{AC}={\vec{AB} . \vec{AC}}

 K_{AB}={\vec{AB} . \vec{AB}}

Selon les valeurs de K_{AC} et K_{AB}, cinq cas peuvent se présenter:

  • K_{AC}<0 : le point n’est pas entre A et B.
  • K_{AC}>K_{AB} : le point n’est pas entre A et B.
  • K_{AC}=0 : les points C et A sont confondus.
  • K_{AC}=K_{AB} : les points C et B sont confondus.
  • 0<K_{AC}<K_{AB} : le point C appartient au segment S.

Code source C++

/*!
 * \brief rOc_segment::isPointOnSegment check if a point is inside the current segment
 * \param point coordinates of the point to test
 * \return  ROC_SEGMENT_INTERSEC_NONE if the point doesn't lay with the segment
 *          ROC_SEGMENT_INTERSEC_EXTREMITY_P1 if the point is merged with P1
 *          ROC_SEGMENT_INTERSEC_EXTREMITY_P2 if the point is merged with P2
 *          ROC_SEGMENT_INTERSEC_CROSS if the point belongs to the segment (extremity no included)
 */
char rOc_segment::isPointOnSegment(rOc_point point)
{
    // A and B are the extremities of the current segment
    // C is the point to check

    // Create the vector AB
    rOc_vector AB=this->vector();
    // Create the vector AC
    rOc_vector AC=rOc_vector(this->point1(),point);

    // Compute the cross product of VA and PAP
    // Check if the three points are aligned (cross product is null)
    if (!( AB.cross(AC).isNull())) return ROC_SEGMENT_INTERSEC_NONE;


    // Compute the dot product of vectors
    double KAC = AB.dot(AC);
    if (KAC<0) return ROC_SEGMENT_INTERSEC_NONE; if (KAC==0) return ROC_SEGMENT_INTERSEC_EXTREMITY_P1; // Compute the square of the segment lenght double KAB=AB.dot(AB); if (KAC>KAB) return ROC_SEGMENT_INTERSEC_NONE;
    if (KAC==KAB) return ROC_SEGMENT_INTERSEC_EXTREMITY_P2;

    // The point is on the segment
    return ROC_SEGMENT_INTERSEC_CROSS;
}

Convertisseur de distances

Dimensionnement de moteur en ligne

Cette page vous permet de dimensionner un moteur entraînant un système mobile. Il est fortement recommandé de consulter cette page avant toute utilisation, cela permettra une meilleure compréhension du calculateur.