
[hack] souris à boule ps/2 comme odometre
#1
Posté 16 janvier 2012 - 12:56
ayant recuperé une souris à boule d'un vieil ordi, je me suis dit que je pourrais l'utiliser comme odomètre pour mon robot.
je l'ai donc cablée comme il faut, et j'ai telechargé la bibliotheque ps/2 ici.
le code d'exemple me permet de detecter le clic sur chaque bouton mais le truc que je comprends pasc'est les valeurs renvoyées pour les axes x et y: je pensais que ça me renverrait les coordonnées de la souris ou au pire un nombre d'impulsions mais la ça me renvoit une valeur proportionelle à la vitesse de rotation de la roue codeuse puis à nouveau 0...
je ne sais pas si c'est le nombre d'impulsions pendant un certain laps de temps, ça serait bien car j'aurais directement la vitesse du robot.
est-ce que quelqu'un a déjà exploité ce genre de resultat ou utisé une souris comme odometre?
le seul truc que j'ai trouvé sur google c'est une "souris-odometre" pour voiture RC très rapide et la personne a modifié les roues codeuses en ne laissant que deux fentes donc le code me renvoit des valeurs fausses et je ne comprends pas trop le code...
merci d'avance
florent
- R1D1 aime ceci
#2
Posté 16 janvier 2012 - 09:27
En théorie en amateur tu ne peux pas exploiter comme bon il te semble une souris à boule comme odomètre, l’exploitation des données est beaucoup trop complexe et demande des algorithmes très compliqués ! Beaucoup ont essayé mais ils ont eu des problème ^^
cdt.
skyhack.
They live inside us and sometimes they win."
-------------Stephen King.------------------
" le fait que les extraterrestres étaient amis avec les Mayas ne signifie pas qu'ils sont nos amis ... "
-------------------------------------Stephen Hawking----------------------------------------------------
#3
Posté 16 janvier 2012 - 09:31
bon ben je me contenterais seulement des optocoupleurs avec les roues codeuses alors...
dommage car le CI m'epargnais la determination du sens de rotation et tout...
je vais quand même voir si je trouve la doc technique du composant, peut-etre qu'il y a moyen de gratter quelques trucs
merci!
#4
Posté 16 janvier 2012 - 06:27
Cdt.
skyhack.
They live inside us and sometimes they win."
-------------Stephen King.------------------
" le fait que les extraterrestres étaient amis avec les Mayas ne signifie pas qu'ils sont nos amis ... "
-------------------------------------Stephen Hawking----------------------------------------------------
#5
Posté 16 janvier 2012 - 08:55
j'ai finalement compris le code que j'avais trouvé sur internet (Photo Gallery) et l'ai adapté à l'utilisation que je voulais en faire...
voici le code:
#include <ps2.h> int distanceX =0; int distanceY =0; unsigned long time1=0, time2=0,delta=0, vitX=0, vitY=0; PS2 mouse(6, 5); void mouse_init() { mouse.write(0xff); // reset mouse.read(); // ack byte mouse.read(); // blank */ mouse.read(); // blank */ mouse.write(0xf0); // remote mode mouse.read(); // ack delayMicroseconds(100); } void setup() { Serial.begin(9600); mouse_init(); } /* * get a reading from the mouse and report it back to the * host via the serial line. */ void loop() { char mstat; char mx; char my; /* get a reading from the mouse */ mouse.write(0xeb); /* give me data! */ mouse.read(); /* ignore ack */ mstat = mouse.read(); mx = mouse.read(); my = mouse.read(); time2=millis(); delta = time2-time1; // calcul de la durée de la boucle if (delta>0) // si delta non-nul { vitX = 1000*abs(mx)/delta; // vitesse = nombre de ticks par durée de boucle (1000-->conversion des ms en s) vitY = 1000*abs(my)/delta; } distanceX+=mx;//distance: somme des ticks (pour une distance en cm, besoin de calibrer distanceY+=my; /* affichage des données */ Serial.print("X="); Serial.print(mx, DEC); Serial.print("\tVitX="); Serial.print(vitX, DEC); Serial.print("\tVitY="); Serial.print(vitY, DEC); Serial.print("\tDistX (en ticks)="); Serial.print(distanceX, DEC); Serial.print("\tDistY (en ticks)="); Serial.print(distanceY, DEC); Serial.println(); delay(20); /* twiddle */ time1=time2; }
il me reste à effectuer les conversions et à utiliser ces valeurs (peut-être dans un premier temps une interface graphique avec le déplacement de la souris puis, si j'y arrive, l'affichage du vecteur de déplacement)
merci pour tout
#6
Posté 18 janvier 2012 - 11:00
j'ai encore continué mon code, il n'est pas encore fini (il me reste le problème de la direction des vecteurs vitesse qui ne marche que pour les déplacements positifs) mais je ferait peut-être un tuto une fois le code terminé.
j'ai mis le rafraîchissement de l'écran en commentaire parce que ça faisait tout scintiller déguelassement donc la trace de tout déplacement reste sur l'écran...
dites moi ce que vous en pensez et si vous avez des solutions aux pb cités ci-dessus!
code arduino:
/* Code: utilisation d'une souris à boule ps/2 comme odomètre avec affichage sur un IG processing par Florent Ecochard */ //=======bibliothèques======= #include <ps2.h> //=========================== //================variables globales=================== int distanceX =0; int distanceY =0; unsigned long time1=0, time2=0,delta=0, vitX=0, vitY=0; //===================================================== //========initialisation souris ps/2========= PS2 mouse(6, 5); //déclaration des E/S de la souris void mouse_init() { mouse.write(0xff); // reset mouse.read(); // ack byte mouse.read(); // blank */ mouse.read(); // blank */ mouse.write(0xf0); // remote mode mouse.read(); // ack delayMicroseconds(100); } //fin mouse_init() //=========================================== void setup() { Serial.begin(9600); // frequence de communication: 9600baud mouse_init(); //appel de la fonction d'initialisation de la souris } //fin setup() void loop() { //=============initialisation communication souris=============== char mstat; char mx; char my; /* get a reading from the mouse */ mouse.write(0xeb); /* give me data! */ mouse.read(); /* ignore ack */ mstat = mouse.read(); mx = mouse.read(); my = mouse.read(); //=============================================================== //==============calculs (vitesses et déplacements)========== time2=millis(); // comptage du tepms delta = time2-time1; // calcul de la durée de la boucle (delta) if (delta>0) { // si delta non-nul vitX = 1000*abs(mx)/delta; // vitesse = nombre de ticks par durée de boucle (1000-->conversion des ms en s) vitY = 1000*abs(my)/delta; } //fin if distanceX+=mx;//distance: somme des ticks (pour une distance en cm, besoin de calibrer) distanceY-=my; //========================================================== //==================transferts (port COM)=================== /* affichage des données (debuggage) Serial.print("X="); Serial.print(mx, DEC); Serial.print("\tVitX="); Serial.print(vitX, DEC); Serial.print("\tVitY="); Serial.print(vitY, DEC); Serial.print("\tDistX (en ticks)="); Serial.print(distanceX, DEC); Serial.print("\tDistY (en ticks)="); Serial.print(distanceY, DEC); Serial.println(); */ Serial.print(vitX, DEC);//transfert de la vitesse selon x Serial.print(" "); //espace permettant de lire les valeurs séparément dans processing Serial.print(vitY, DEC); Serial.print(" "); Serial.print(distanceX, DEC); Serial.print(" "); Serial.print(distanceY, DEC); Serial.print(" "); Serial.println(); //saut de ligne delay(20); /* twiddle */ time1=time2; //========================================================== } //fin loop()
code processing (non-commenté sauf quelques commentaires en anglais qui viennent de morceaux de code copiés-collés):
import processing.serial.*; Serial myPort; // The serial port //------ déclaration des variables de couleur utiles ---- int jaune=color(255,255,0); int vert=color(0,255,0); int rouge=color(255,0,0); int bleu=color(0,0,255); int noir=color(0,0,0); int blanc=color(255,255,255); int bleuclair=color(0,255,255); int violet=color(255,0,255); //--- variables globales int xO=0, yO=0; float xf=0.0, yf=0.0; int xPos = 1; // horizontal position of the graph void setup(){ // fonction d'initialisation exécutée 1 fois au démarrage println(Serial.list()); myPort = new Serial(this, Serial.list()[1], 9600); myPort.bufferUntil('\n'); // ---- initialisation paramètres graphiques utilisés colorMode(RGB, 255,255,255); // fixe format couleur R G B pour fill, stroke, etc... fill(255,0,0); // couleur remplissage RGB - noFill() si pas de remplissage stroke (0,0,0); // couleur pourtour RGB - noStroke() si pas de pourtour rectMode(CENTER); // origine rectangle : CORNER = coin sup gauche | CENTER : centre imageMode(CENTER); // origine image : CORNER = coin sup gauche | CENTER : centre ellipseMode(CENTER); // origine cercles / ellipses : CENTER : centre (autres : RADIUS, CORNERS, CORNER strokeWeight(1); // largeur pourtour frameRate(60);// Images par seconde - The default rate is 60 frames per second // --- initialisation fenêtre de base --- size(600, 600); // ouvre une fenêtre xpixels x ypixels background(255,255,255); // couleur fond fenetre } void draw() { repere(width/2, 580); //dessine le repere } void repere(int xO,int yO) { line(0,yO,width,yO); //axe des abscisses line(xO,0,xO,height); // axe des ordonnées ellipse(xO,yO,5,5); // origine } void serialEvent (Serial myPort) { try { String vitX = myPort.readStringUntil(' '); String vitY = myPort.readStringUntil(' '); String distX = myPort.readStringUntil(' '); String distY = myPort.readStringUntil(' '); if (vitX != null && vitY != null) { // on vire les espaces vitX = trim(vitX); vitY = trim(vitY); distX = trim(distX); distY = trim(distY); // on convertit en nombres float vitX_b = float(vitX); float vitY_b = float(vitY); float distX_b = float(distX); float distY_b = float(distY); ellipse(distX_b+width/2, distY_b+580,20,20); // robot line(distX_b+width/2, distY_b+580, distX_b+width/2+vitX_b, distY_b+580-vitY_<img src='http://www.robot-maker.com/forum/public/style_emoticons/<#EMO_DIR#>/cool.gif' class='bbc_emoticon' alt='B)' />; //vecteur vitesse } /* background(255,255,255); repere(width/2, 580); */ } catch (Exception e) { println("Initialization exception"); } }
ps: le try{} et catch{} servent à éviter un problème avec le port COM, j'ai trouvé cette solution sur internet
#8
Posté 19 janvier 2012 - 08:26
voici une petite video:

--> première phase: déplacement "normal"
deuxième phase: déplacement "problématique": vecteur dans le mauvais sens
troisième phase: déplacement à petite vitesse
quatrième phase: déplacement grande vitese
j'ai rajouté ces lignes de code:
if (keyPressed == true){ if (key == 'c') { background(255,255,255); repere(width/2, 580); } }afin de pouvoir effacer l'écran entre les phases pour plus de clarté.
voici des photos du montage:



#9
Posté 21 janvier 2012 - 11:55

J'avais moi-même démonté une souris optique à l'époque pour essayer de m'en servir pour de l'odométrie également. Mais faute de temps je n'ai jamais pu mener le projet à bien. Toi en revanche, tu avances bien ! Bonne continuation.
Esprit
*Rêve d'en caser un dans un robot*
#12
Posté 21 janvier 2012 - 10:39

Je vais essayer de régler le problème de direction mais je ne pense pas utiliser ce système sur mon robot finalement: ça présente trop d’inconvénients (précision, non détection de rotations etc.)
je m'en servirait peut-être dans un autre projet avec un robot plus petit et moins rapide...
je vous tiens au courant si je réussis à corriger tout ça

#13
Posté 20 février 2012 - 07:01
Je ne suis pas trop d'accord avec les affirmations de Skyhack.
Utiliser une souris à boule telle quelle, ça ne peut pas fonctionner. 2 souris à boule, c'est mieux, mais ce qui est encore mieux, c'est d'utiliser l'électronique et/ou la mécanique d'une souris à boule pour en faire des codeurs que tu peux monter sur tes roues de propulsions (ou sur des roues dédiées à l'odométrie).
Oui, les roues codeuses des souris à boule sont de TRES BONS CAPTEURS!
Voici en vrac les trucs qu'il faut savoir:
- Pour des codeurs, c'est facile à utiliser, et assez robuste, peu sensible au désalignement, contrairement à des codeurs plus précis.
- Ca n'est pas super performant : ça a une fréquence limite au delà de laquelle tu ne peux pas aller. Je ne pense pas, par exemple, que l'on puisse mettre la roue codeuse d'une souris à boule sur le moteur de propulsion en amont du réducteur. Mais monté côté roue, ça fonctionne très bien!
- une souris est bien censée renvoyer les déplacements x-y entre 2 lectures. Attention, il faut lire assez fréquemment, car sinon, le petit compteur de la souris arrive assez vite à saturation et alors tu perds des données.
- dans la logique de la souris, il y a un réglage à faire : dans la souris, et dans l'OS, il y a un facteur multiplicatif qui fait que la souris peut renvoyer des déplacements plus grands que la normale si elle va à vitesse élevée. C'est pour l'ergonomie, mais ça nous fait chier pour nos capteurs. Il faut désactiver cette fonction, à toi de trouver la doc nécessaire, sur les instructions qu'il faut renvoyer à la souris.
- la précision est bonne, voire très bonne. En fait, comme tout codeur, une roue de souris à boule ne perd aucun front si elle est utilisée dans la bonne plage de fonctionnement (bien réglée, utilisée à vitesse raisonnable).
- Contrairement à ce que dit Skyhack, une souris à boulle sait très bien dans quel sens ça tourne, et ne perd aucun front pour déterminer le sens d'avancement (contrairement à d'autre types de capteur rotatif). C'est en fait vrai pour n'importe quel codeur qui fonctionne avec des signaux en quadrature.
J'ai utilisé cette solution dans 2 robots différents:
- Sur BOB2 (pas de site complet), j'utilisais toute l'électronique de la souris, donc ça ressemble beaucoup à ce que tu veux faire, swolf. Voir le chapitre "elec" du site.
- sur BOB3, je n'ai utilisé que les fourches optiques et les roues codeuse, et toute l'électronique est faite "maison" avec un HCTL2032 pour exploiter les codeurs. Voir le chapitre capteurs du site.
Et si tu as des questions, n'hésites pas à me faire signe. Je ne garantis pas le délai de réponse cependant.
Leon.
BOB4, mon drone hélicoptère autonome d'intérieur http://heli.bot.free.fr/
BOB3, mon robot autonome d'intérieur avec WiFi + Foxboard Linux http://ze.bot.free.fr/
BOB5, robot bipède simulé, puis tentative de réalisation (fail)
#14
Posté 23 février 2012 - 08:11
pas de problème pour le retard, je suis pareil que toi

Pour le bob2, celui où tu utilises toute l'électronique de la souris, t'as utilisé quoi comme type de code? tu as aussi compté les impulsions données par le CI? parce que je me dis que'en fait, ça ne sert à rie de le garder si il ne fait que compter les impulsions et déterminer le sens de rotation... Peut-être qu'il vaut mieux uniquement garder les codeurs...
en tout cas bravo pour tes robot, ils sont supers!
#15
Posté 24 février 2012 - 07:01
En fait, BOB2 était réalisé (il n'existe plus) à partir des restes d'un vieux PC portable (486). Donc la souris était directement branchée sur le port PS/2, avec le driver souris intégré à l'OS (MS DOS). Donc ça n'a rien à voir avec l'arduino que tu utilises.Pour le bob2, celui où tu utilises toute l'électronique de la souris, t'as utilisé quoi comme type de code? tu as aussi compté les impulsions données par le CI? parce que je me dis que'en fait, ça ne sert à rie de le garder si il ne fait que compter les impulsions et déterminer le sens de rotation... Peut-être qu'il vaut mieux uniquement garder les codeurs...
Sinon, oui, je te confirme que l'électronique de la souris ne fait "que" compter les impulsions, en prenant en compte le sens de rotation. J'avoue que je ne sais pas s'il est facile de faire la même chose avec un Arduino (compter des tops en prenant en compte le sens). A toi de fouiller sur le web. Sur BOB3, j'ai carrément un composant dédié pour faire ça: le HCTL2032.
Leon.
BOB4, mon drone hélicoptère autonome d'intérieur http://heli.bot.free.fr/
BOB3, mon robot autonome d'intérieur avec WiFi + Foxboard Linux http://ze.bot.free.fr/
BOB5, robot bipède simulé, puis tentative de réalisation (fail)
#16
Posté 16 juillet 2012 - 04:26
Très bonne idée de n'utiliser que l'électronique d'une souris à boule pour faire une roue codeuse, cependant comment vous mettez en œuvre l'électronique : tension d'alimentation, résistance pour la diode, pour le transistor.......?
J'ai deux solutions à disposition des fourches optiques d'imprimantes et des fourches optiques de souris sachant que ces dernières me semblent plus avantageuses pour détecter le sens de rotation puisque deux capteurs par fourche....
Merci pour vos commentaires.
#17
Posté 16 juillet 2012 - 04:29
#19
Posté 18 juillet 2012 - 12:45
Alors pour certains je ne leur apprendrai rien mais voici le principe de fonctionnement d'une souris à boule composé de deux roues codeuses et de deux boutons, c'est un modèle IBM avec câble PS/2. J'ai fait deux images qu'il faut superposer pour voir l'emplacement des différents composants....

Les fourches optiques sont composées (chacune ) d'une Led IR et de deux capteurs. Celles-ci, fournissent les signaux en quadrature analyser par le CI EMB54802AP qui délivre sur sa sortie DATA un signal composée de 3 Byte.
Ces 3 Byte sont espacés d'environ 350 µs ; les trames ainsi constituées durent alors 3,6 ms et sont espacées d'au moins 6,4 ms. Ainsi, la souris pourra envoyer jusqu'à 100 trames par seconde.

Le premier Byte de la trame fournit les informations suivantes :
L : Bouton Gauche (actif à 1)
R : Bouton Droit (actif à 1)
XS : Direction du déplacement horizontal (1 pour Gauche)
YS : Direction du déplacement horizontal (1 pour Bas)
XV : Débordement suivant X
YV : Débordement suivant Y
Les 2 Byte suivants transportent la valeur du déplacement :
X[7..0] : Déplacement Horizontal (Entier relatif, positif à droite)
Y[7..0] : Déplacement Horizontal (Entier relatif, positif en bas)
C'est relativement bref comme information mais je pense que le nécessaire est présent.
Source : http://www.rennes.su.../souris_ps2.htm
- swolf aime ceci
#20
Posté 18 juillet 2012 - 01:06

Répondre à ce sujet

1 utilisateur(s) li(sen)t ce sujet
0 members, 1 guests, 0 anonymous users