Outils pour utilisateurs

Outils du site


robotics:odometrie

Ceci est une ancienne révision du document !


ODOMETRIE

L'odométrie est une technique de localisation relative d'un robot. En mesurant tous les déplacements du robot depuis son point d'origine, il est possible de calculer à chaque instant sa position et son orientation sur la table.

Principe

Un odomètre (roue codeuse placée au centre du robot) nous permet de connaître la distance parcourue par le robot. Cette seule information de distance ne permet pas de positionner le robot dans un système de coordonnées.

Pour cela, il faut 2 odomètres (roues codeuses indépendantes ou montées directement sur les moteurs). A chaque intervalle de temps, on mesure la distance parcourue par les roues droite et gauche.

Approximation par segment de droite

On suppose que la trajectoire du robot est découpée en une série de segment. A chaque intervalle de temps, le robot effectue un déplacement rectiligne suivant son orientation précédente.

Distance moyenne du robot

La distance moyenne parcourue par le robot est la distance moyenne parcourue par les 2 roues du robot : Δdr = (Δdd + Δdg) / 2.

Orientation du robot

La différence entre les 2 roues nous donne l'orientation du robot : Δθ = atan[(Δdd - Δdg) / entraxe]

On peut considérer que Δθ ne varie pas beaucoup entre 2 mesures donc grâce à l'approximation de Gauss, on peut écrire : Δθ = (Δdd - Δdg) / entraxe

Coordonnées du robot

On peut maintenant définir la nouvelle position du robot et son orientation.

Δx = Δdr.cos θA

Δy = Δdr.sin θA

xB = xA + Δx

yB = yA + Δy

θB = θA + Δθ

Conclusion

Cette méthode est très simple à mettre en œuvre sur un petit microcontroleur. Par contre, l'approximation est assez grossière et peut engendrer une dérive assez importante sur un parcours long.

Approximation par arc de cercle

La trajectoire du robot est découpée en une série d'arc de cercle. A chaque intervalle de temps, le robot effectue un arc de cercle de rayon R et d'angle a.

Distance moyenne du robot

La distance moyenne parcourue par le robot est la distance moyenne parcourue par les 2 roues du robot : Δd = (Δdd + Δdg) / 2.

Orientation du robot

La différence entre les 2 roues est un arc de cercle qui a pour rayon l'entraxe des 2 roues. L'angle de l'arc nous donne l'orientation du robot :

Δθ = (Δdd - Δdg) / entraxe

Rayon de courbure

En considérant le rayon R au milieu de l'entraxe e des 2 roues on a : R = Δd / Δθ

Coordonnées du centre de l'arc

A partir de la position du robot et de son orientation, on va pouvoir définir le centre de l'arc de cercle O.

xO = xA - R.sin θA

yO = yA + R.cos θA

Coordonnées du robot

On peut maintenant définir la nouvelle position du robot :

θB = θA + Δθ

xB = xO + R.sin θB

yB = yO - R.cos θB

Cas particulier où Δθ = 0, on a :

xB = xA + Δd.cos θB

yB = yA + Δd.sin θB

Conclusion

Cette approximation est plus précise que l'approximation par segment mais nécessite plus de calcul.

Implementation

typedef struct
{
  double x;     /* en pulse */
  double y;
  double O;     /* en rad */
} position;
 
/* mise a jour la nouvelle position du robot (x, y, O)
 * par approximation de segment de droite */
void
calcul_position_segment(position *p, double distance, double angle)
{
  p->x += distance * cos(p->O);
  p->y += distance * sin(p->O);
  p->O += atan2(angle, entraxe);
}
 
/* mise a jour de la nouvelle position du robot (x, y, O)
 * par approximation d'arc de cercle */
void
calcul_position_arc(position *p, double distance, double angle)
{
  /* rayon et angle de l'arc de cercle */
  double r, a;
  /* coordonnées du centre de l'arc de cercle */
  double xo, yo;
 
  if (angle == 0)
    {
      p->x += distance * cos(p->O);
      p->y += distance * sin(p->O);
    }
  else
    {
      /* calcul des caractéristiques de l'arc de cercle */
      a = angle / entraxe;
      r = distance / a;
 
      /* centre de l'arc de cercle */
      xo = p->x - r * sin(p->O);
      yo = p->y + r * cos(p->O);
 
      /* coordonnees du robot */
      p->O += a;
      p->x = xo + r * sin(p->O);
      p->y = yo - r * cos(p->O);
    }
}
 
/* delta_roue_droite et delta_roue_gauche sont les distance en pulses
 * parcourue par les roues droite et gauche en un cycle */
void
odometrie(position *p, signed short delta_roue_droite,
    signed short delta_roue_gauche)
{
  double delta_distance = 0, delta_angle = 0;
 
  delta_distance = ((double) (delta_roue_droite + delta_roue_gauche)) / 2;
  delta_angle = (double) (delta_roue_droite - delta_roue_gauche);
 
  //calcul_position_segment(p, delta_distance, delta_angle);
  calcul_position_arc(p, delta_distance, delta_angle);
}

Conclusion

Pour des mesures régulières et fréquences dans un environnement restreint (table eurobot 2 x 3 m), les deux approximations sont sensiblement équivalentes. Nous avons effectué les calculs sur une ARDUINO UNO et tracé les deux courbes qui sont quasiment identiques.

robotics/odometrie.1370349650.txt.gz · Dernière modification: 2013/06/04 14:40 par ldo