Mécatronique Application avec le lego Mindstorm EV3
Imag
e S
ourc
e: [t
echc
amp]
Mécatronique : • l’intégration en synergie de la mécanique, l’électronique,
l’automatique et l’informatique dans la conception d’un système en vue d’optimiser sa fonctionnalité (Norme NF E 01-010)
Imag
e S
ourc
e: [H
elix
84]
Exemple autour du lego Mindstorm
Sommaire
1. Lego EV3 Hardware 1) La brique EV3 2) Les moteurs et capteurs
1bis. Robotique mobile et le tribot (notre sujet de TP)
2. Lego EV3 Programming 1) L’environnement RobotC 2) Le langage RobotC 3) L’API (les fonctions disponibles)
1. EV3 Hardware
EV3 Hardware (overview) Moteurs: -commande en vitesse -codeur incrémental de position (résolution: 1°)
Capteur contact: -pressé (1), relâché(0)
Brique EV3 (CPU + batterie): -Ecran LCD -LED -Haut parleur -Boutons
Capteur ultrason: -distance obstacle (cm)
Capteur gyroscopique 1axe: -vitesse angulaire (°/s) -angle (par intégration °)
LED + photodiode: -couleur -lumière réfléchie (%)
Capteurs/Entrées Actionneurs/Sorties
La brique EV3 Nom de la brique USB :
si connexion établie avec un périphérique
Charge de la batterie
Etat connexion bluetooth
Bouton Retour : -Annuler -Stopper un programme -Eteindre la brique Bouton Central : -Valider -Allumer la brique Bouton gauche,droite, haut,bas : -Naviguer dans les menus
1
2
3
Spéc. techniques : - Processeur 300MHz - Ecran 178x128 pixels - Noyau Linux - 16 Mo FLASH - 64 Mo RAM
La brique EV3
Rouge : -démarrage - arrêt du système Rouge clignotant: - occupé
Orange : - alerte - prêt Orange clignotant: - alerte - programme en cours
Vert : - prêt Vert clignotant : - programme en cours
Code couleur (par défaut) des leds :
La brique EV3 Port pour les capteurs: S1, S2, S3, S4
Vue de dessous Vue de dessus
Vue de gauche Vue de droite
Port USB connexion avec le PC
Port pour les moteurs: A,B,C D
Batterie Haut-parleur
Prise chargeur de la batterie
Port d’extension de mémoire : Carte SD
Port USB pour périphérique
Menus
Menu Récent: - liste des derniers programmes exécutés - permet de les relancer
Menu Réglage: - volume - mise en veille - bluetooth/wifi - info brique
Menu Utilitaires: - Port view : test capteur, position moteur - Motor control : test des moteurs
Menu Fichiers: -explorateur de fichiers -lancer tout programme -effacer le contenu d’un répertoire
Utilitaire Port view • Menu Utilitaire • Affiche la valeur mesurée par les capteurs, dont les codeurs de position
Valeurs courantes des codeurs, ports A, B, C, D.
Valeurs courantes des capteurs, ports S1, S2, S3, S4.
Les moteurs
Moteurs à courant continu - avec balai (brushed DC motor) + train d’engrenage pour augmenter le couple - couple moteur τ, créé par force de Laplace sur le fil :
, avec i le courant du rotor
dF = i dl∧B
τ = K i
Imag
es s
ourc
e: [d
cmot
or]
Les moteurs Modèle électrique et mécanique du moteur DC
U = L didt+ Ri+Uemf
Uemf = Kω
!
"#
$#
J !ω = τ − bωτ = K i
"#$
%$
Imag
es s
ourc
e: [d
cmod
el]
ωU(s) = K
(Ls+ R)(Js+ b)+K 2
Fonction de transfert :
Ø En régime permanent et pour un charge constante sur le moteur : La vitesse du moteur ω est proportionnelle à U.
Les moteurs
O V
9 V
90% duty cycle
O V
9 V10% duty cycle
Moteur commandé en tension : - par modification du rapport cyclique en % d’un signal PWM à 8 kHz - si non régulé (boucle ouverte): si charge mécanique ì, vitesse î pour un même U
10% : Umoy=0.9V
90% : Umoy= 8.1V
Ø La commande du moteur est exprimé en % de la tension de la batterie
Les moteurs
Pont H (H-bridge): - pilote le sens de rotation et freinage dynamique (electronic braking) - constitué de 4 interrupteurs commandés (transistors Q1, Q2, Q3, Q4)
M+ M-
+Ve
-Ve
Q1
Q2
Q3
Q4
Tous interrupteurs ouverts : moteur non alimenté (float)
Imag
e so
urce
: [hb
ridge
]
Les moteurs
+ - + -
Q1 et Q4 haut : moteur avance Q2 et Q3 haut : moteur recule
Q3 et Q4 haut : freinage – electronic braking (si moteur en rotation)
U=0 et moteur en rotation ω >0 , moteur en mode générateur court-circuité : Le courant induit par la rotation crée ici un couple opposé au mouvement.
0 = Ri+Uemf
Uemf = Kω > 0
!"#
$#
i = −Uemf
R< 0
τ = K i < 0
"
#$
%$
Les moteurs : capteur de position
Codeur incrémental optique : - disque ajouré de fentes - passage des fentes détecté par 2 photodiodes - sens rotation donné par la voie en avance de phase sur l’autre
Imag
e so
urce
: [en
code
r] Im
age
sour
ce: [
Phi
lo]
Le capteur de couleur 3 modes de fonctionnement: • Couleur ( 7 couleurs codées ou composantes RGB ) • Lumière réfléchie
LED active (en % d’intensité lumineuse) 0%= sombre, 100%=clair
• Lumière ambiante
LED inactive (en % d’intensité lumineuse)
LED rouge
Cellule photosensible
Mesure lumière réfléchie (en %) Mode couleur
Les capteurs
Capteur de contact: - analogique - ferme un interrupteur - 2 états
1 =Pressé
2 =Relâché
Gyroscope, vitesse angulaire et angle 1 axe: - angle par intégration de la vitesse (dérive au cours du temps !) - vitesse maximale mesurée: 440°/s Micro Electo-Mecanical System (MEMS) -mesure force Coriolis sur structure vibrante
Image source: [electroiq]
Les capteurs Le capteur ultrason: -mesure de distance via un temps de parcours Limitations : a. distance max mesurée: 25cm b. angle entre obstacle plan et capteur < 45° c. objet petit ou absorbant = invisible d. interférence entre 2 capteurs
d.
?
Images source: [escplanta]
1bis. Robotique mobile et le robot tribot
• Le robot tribot est le sujet d’étude des TPs
2. EV3 Programming
2. EV3 Programming
librobotc.so (bibliothèque dynamique robotC)
sourceFile1 (exécutable)
Logiciel RobotC : -un éditeur de cource -un compilateur -un téléchargeur via usb
1. Edition du source
4. Exécution
3. Téléchargement (via usb)
2. Compilation
sourceFile1 (exécutable)
sourceFile1.c
2.1 RobotC, l’environnement
Compiler
Compiler et télécharger
1
2
3
Installer la bibliothèque RobotC sur l’EV3 (uniquement la première fois)
Réglage moteurs et capteurs
Créer, ouvrir, sauver un fichier source
1
2 3 Erreur compilation, débogage Editeur de source
Liste des fonctions (avec glisser-déposer dans le source et aide contextuelle disponibles)
Configuration de RobotC 1. Menu Robot : -la cible de compilation est le robot physique -la plateforme est le Lego EV3 sans le « natural language »
2. Menu Windows -> Menu level : -définie le nombre de fonctions affichées dans la fenêtre ’’liste des fonctions’’’ -Expert est recommandé (Basic cache les fonctions pour l’écran LCD)
Start et débogage
Start/stop programme
Step Into : -démarre et avancer en mode une instruction par clic
Pause/Resume : -pauser ou reprendre l’exécution normale
Le bouton « télécharger sur le robot » ouvre le mode débogage: -démarrer, exécuter instruction par instruction, arrêter le programme -visualiser l’état courant des variables, capteurs et moteurs (monitoring via l’USB)
Quitter le débogage
Etat courant des variables locales Note : pour afficher aussi les capteurs (menu Robotà debugger windows -> sensors)
Start et débogage
Pour démarrer le programme à partir de la brique EV3 (sans connexion au PC) Ø sélectionner votre programme dans le Menu files de l’EV3, répertoire RC
2.2 Le langage RobotC
Langage C avec des exceptions simplificatrices: • Pas de fonction main() mais une task main()
à une programmation multi-tâche simplifiée • Des nouveaux types : string pour les chaines de caractères char msg[6]="allo!"; à string msg="allo!"; • Pas d’allocation dynamique
à uniquement des tableaux statiques int tab[5]; • Un prototype doit obligatoirement inclure le nom des paramètres effectifs + utiliser la notation func(int tab*) et non func(int tab[])
Les commentaires
/* Ceci est un commentaire (ansi C style)*/ ou /* Ceci est un commentaire
(ansi C style)*/
// Ceci est un commentaire (C++ style)
ou // Ceci est un commentaire
// (C++ style)
Les types type Plage de valeurs Taille mémoire int -32768 à +32767 2 octets long -2147483648 à +2147483647 4 octets float ± xxx 10±xx 4 octets char 0 à 255 1 octet string chaîne de 20 char 20 octets (20 char)
• pas de double, nombre à virgule en double précision • des types supplémentaires existent (sans utilité): byte, ubyte, bool
• Le type string remplace les chaines de caractère char[] limité à 20 caractères = nombre de caractères qui tiennent sur la largeur de l’écran
Introduit (du C++) pour faciliter la manipulation des chaînes
• Affectation string a="allo!"; string b; a ="a l’huile"; b=a; • Concatenation string c="tic-"; c=a + "tac"; /*c vaut "tic-tact"*/
Equivalant en C-ansi: Char a[20]="allo!"; Char b[20]; strcpy(a,"a l’huile"); strcpy(b,a); char c[20]="tic-"; strcat(c,"tac");
Le type string
• Test string a="allo!"; string b; if (a==b) {/* a et b identique*/} • Passage implicite par adresse { display(ma); } void display(string c) {c="toto"; /*modifier c, modifie aussi la variable ma */ }
Equivalant en C-ansi: Char a[20]="allo!"; Char b[20]; if (!strcmp(a,b)) {/*a et b idetique*/} Seul passage par adresse.
Le type string
Le type string Quelques fonctions : • strcat, strcmp, strlen strcpy sont définis pour les strings
string msg="un test";
int length= strlen(msg);
• sprintf(string, "format", var1,var2,…) écrit dans le string le message correspondant au format précisé
string mesg;
int a=-1;
sprintf(mesg,"i: %d",a); ßà mesg="i: -1";
Les fonctions math Voir liste des fonctions disponibles. On note cependant : • float cos(float fRadians) • float sin(float fRadians)
retournent le cosinus/sinus d’un angle en radians.
• const float PI une constante valant π.
Exemple : float oneTurn =2*PI;
Structure de contrôles Identiques au C: • if (condition) … • if (condition) … else …
• for ( ; ; ) … • while(condition) … • do … while (condition);
Attention: robotC autorise l’absence de cette virgule.
Le multitâche Chaque programme contient au moins une tâche initiale: task main() ßà fonction main() du C-ANSI
• La tâche prend fin à la fin de ses instructions. • Lorsque toutes les tâches sont finies, le programme s’arrête.
task main() { int speed=30; setMotorSpeed(motorB, speed); … }
source.c
Le multitâche • On peut créer une tâche infinie
(tant que l’on n’appuie pas sur le bouton d’arrêt):
task main() { int speed=30; setMotorSpeed(motorB, speed); setMotorSpeed(motorC, 30); while (1);
}
source.c
à Les moteurs tournent indéfiniment.
Moteurs B et C à 30% de leur vitesse.
Le multitâche • On peut créer une tâche périodique:
task main() { int speed=30; while(1) { playTone(400,20); sleep(2000); }
}
source.c
temps
Usage du CPU par tâche main
2000 ms
Joue un note à 400Hz pendant 20x10ms
Attente/stoppe l’exécution pendant 2000 ms
playTone() playTone() playTone() playTone()
Le multitâche Multitâche : plusieurs tâches peuvent tourner en parallèle • void startTask( task_name)
permet à une tâche de démarrer en parallèle la tâche de nom task_name
• void stopTask( task_name) permet à une tâche de stopper la tâche de nom task_name
• void stopAllTasks() stoppe toutes les tâches dont la tâche principale à Stoppe le programme.
Le multitâche
temps
Usage du CPU:
2000 ms
playTone()
task beep(); /*prototype*/ task main() { startTask(beep); while(time1(T1)<3000) { setMotorSpeed(MotorB,30); setMotorSpeed(MotorB,30); } stopTask(beep); } task beep() { while(1) { playTone(400,20); sleep(2000); } }
setMotorSpeed setMotorSpeed setMotorSpeed ….
task beep task main
à les moteurs reçoivent en boucle une commande de vitesse pendant 3s, pendant que l’autre tâche émet un bip toutes les 2s.
Le multitâche
temps
Usage du CPU:
2000 ms
playTone()
task beep(); /*prototype*/ task main() { startTask(beep); while(time1(T1)<3000) { setMotorSpeed(MotorB,30); setMotorSpeed(MotorB,30); sleep(400); } stopTask(beep); } task beep() { while(1) { playTone(400,20); sleep(2000); } }
setMotorSpeed setMotorSpeed
task beep task main
Nécessaire pour que le programme se finisse
Pas nécessaire de renvoyer la commande moteur sans répit (et saturer le CPU): la vitesse est maintenue tant qu’il n’y a pas de nouvelle commande. à un sleep() une bonne idée !
Le multitâche Communication entre plusieurs tâches : Ø Utiliser des variables globales. Toute tâche ou fonction peut accéder à ces variables.
Prototypes et fonctions • Particularités RobotC pour les fonctions :
• le prototype doit inclure les noms des arguments tels qu’à la définition • la notation func(int tab[]) n’est pas tolérée
àutiliser la notation func(int tab*)
int somme(int *tab); /*int somme(int*) rejeté*/ task main() { int tab[2]={1,2}; int a; a=somme(tab); } int somme(int*tab) { return tab[1]+tab[2] ;}
2.3 L’interface de programmation
API (Application Programming Interface ) dont liste des fonctions disponibles
L’écran LCD
• 16 lignes d’affichage, n° 0 à 15 • un caractère : 6x8 pixels • un Big caractère : 12x16 pixel
à Un Big caractère occupe 2 lignes
178 pixels (29 caractères)
128 pixels ( 16 lignes [0…15] d’affichage)
task main() { string msg="Bonjour!"; float f=1; displayBigTextLine(0, "%s - %f",msg, f); displayCenteredTextLine(8,"allo!"); }
Bonjour! - 1.000
allo!
L’écran LCD • void eraseDisplay()
efface complètement l’écran • void displayTextLine(int Line, string Format, ..)
affiche sur la ligne de numéro Line la chaîne correspondant au Format le reste de la ligne est rempli de blancs
• void displayCenteredTextLine(int Line, string Format,..) idem displayTextLine mais le texte est centré au milieu de l’écran
Les même fonctions mais pour des gros caractères: • void displayBigTextLine(int Line, string Format,...) • void displayCenteredBigTextLine(int Line, string Format,
Le temps • void sleep(long ms) • void delay(long ms)
l’instruction bloque pendant ms millisecondes i.e. on passe à l’instruction suivante après ms millisecondes
La mesure du temps écoulé:
-un timer compte le nombre de millisecondes écoulées -4 timers sont disponibles d’ID: T1,T2,T3 et T4
• clearTimer(timerID) remet à 0 le timer en argument
• long time1(timerID) -retourne le temps écoulé depuis le reset en millisecondes
Le temps task main() {
long temps;
clearTimer(T1);
sleep(1654);
sleep(1000);
temps=time1(T1);
displayTextLine(8,"elapsed time: %i,temps);
}
L’affichage à l’exécution est : elapsed time: 2601
Le son
• void setSoundVolume(int Volume) règle le volume sonore de la brique (0 (off) -100 (max))
• void playTone(int frequency, int 10MsecTicks) joue la note de fréquence frequency pendant une durée de 10MsecTicks x 10 millisecondes
• void playSound(TSounds sound) joue un son du système. Sont disponibles (voir documentation):
• soundBlip • soundBeepBeep • …
Les capteurs et moteurs : setup Setup, pour indiquer au compilateur:
• quels sont les capteurs connectés ? • sur quels ports sont ils connecté ? • dans quel mode de fonctionnement ? • quel noms/identifiants leur donne t’on ?
• quel est le type de moteur ? • quel nom/identifiant lui donne t’on ? • est il piloté en boucle ouverte ou asservie en vitesse (boucle fermé) ?
Les capteurs et moteurs : setup Ouvrir la fenêtre setup (ci-dessous)
Port de la brique EV3 (où est connecté le capteur) 1.Choisir le type du capteur connecté
ou no sensor
2.Choisir un identifiant alias (son nom dans le code c)
3.Choisir le mode de fonctionnement
Les capteurs et moteurs : setup Les modes de fonctionnement des capteurs : • ultrason : 1. distance en cm
2. distance inch • contact : 1. mode touch (1 contact ou 0 non)
• gyroscope : 1. angle only 2. rate only (vitesse angulaire)
3. angle and rate? • capteur de couleur:
1. reflected (lumière réflechie) 2. ambient (lumière ambiante) 3. color (mesure couleur) Le modes raw donne des valeurs non normalisées entre 0 et 100%.
Les capteurs et moteurs : setup
1.Choisir un nom/identifiant
2.Type du moteur
Inutile: mettre None
Medium Large
3. Si on veut inverser le sens de rotation positif d’un moteur
4. Commande vitesse en boucle ouverte ou asservie (boucle fermé :PID avec vitesse dérivée du codeur du moteur)
#pragma config(Sensor, S1, gyroscope, sensorEV3_Gyro, modeEV3Gyro_RateAndAngle) #pragma config(Sensor, S2, color_sensor, sensorEV3_Color)
#pragma config(Sensor, S3, ultrason, sensorEV3_Ultrasonic)
#pragma config(Sensor, S4, touch1, sensorEV3_Touch)
#pragma config(Motor, motorA, armMotor, tmotorEV3_Medium, PIDControl, encoder)
#pragma config(Motor, motorB, leftMotor, tmotorEV3_Large, PIDControl, encoder)
#pragma config(Motor, motorC, rightMotor, tmotorEV3_Large, PIDControl, encoder)
#pragma config(Motor, motorD, , tmotorEV3_Large, openLoop)
//*!!Code automatically generated by 'ROBOTC' configuration wizard !!*//
Les capteurs et moteurs : setup
Source.c :
Une fois le setup validé, le code correspondant à la configuration est automatiquement inséré dans le source.
PS: rien n’interdit d’écrire ce code de préprocesseur sans passer par l’interface graphique.
Les capteurs • float getUSDistance(tSensors capteur) retourne la distance dans l’unité correspondant au mode; le capteur est soit le port S1,S2,S3,S4 ou le nom d’alias défini dans le setup pour le capteur ultrason. • bool getTouchValue(tSensors capteur) retourne 1 si capteur pressé, 0 sinon • void resetGyro(tSensors capteur) remet à 0 l’angle du gyroscope • long getGyroDegrees(tSensors capteur) retourne l’angle accumulé par le capteur en degrés le signe indique la direction (positif=sens trigonométrique) • long getGyroRate(tSensors capteur) retourne la vitesse angulaire signée en degrés/seconde
Les capteurs En fonction du mode sélectionné pour le capteur de couleur: • int getColorReflected(tSensors capteur) retourne en % (0-100) la quantité de lumière réfléchie (LED on) • int getColorAmbient(tSensors capteur) retourne en % (0-100) la quantité de lumière reçue (LED off)
• TLegoColors getColorName(tSensors capteur) retourne une valeur entre 0 et 7 correspondant à une couleur la valeur reçue peut être stockée dans un int et comparée aux constantes: colorNone, colorBrown, colorWhite, colorRed, colorYellow, colorGreen, colorBlue, colorBlack
Les capteurs
task main() {
int color;
setMotorSpeed(leftMotor,50);
while(1)
{ color=getColorName(S3);
if (color==(int)colorRed)
{ playSound(soundBeepBeep);}
if (getTouchValue(touchSensor)==1)
{setMotorSpeed(leftMotor,0);}
if (getUSDistance(sonarSensor)<10)
playSound(soundException);
sleep(100);
}
}
Si couleur détectée rouge, jouer un son
En cas de contact, stopper moteur
En cas d’obstacle à 10 cm, jouer un son.
Le moteur
Le codeur de position incrémental:
• void resetMotorEncoder(tMotor Motor) remet à 0 la position du moteur; le moteur Motor correspond à un port motorA,motorB, motorC, motorD ou un nom d’alias défini dans le setup.
• float getMotorEncoder(tMotor Motor)
retourne la valeur courante du codeur du moteur en degrés
Les capteurs
task main() {
resetMotorEncoder(leftMotor);
setMotorSpeed(leftMotor,50);
while( getMotorEncoder(leftMotor) < (360*2) )
{}
setMotorSpeed(leftMotor,0);
}
Exemple : Tant que la roue n’a pas fait 2 tours, avancer à 50% de la vitesse max.
Le moteur
La commande en vitesse des moteurs: • void setMotorSpeed(tMotor Motor, int speed)
speed est compris entre 100%(vitesse max) et -100% (vitesse max en sens inverse), 0 met le moteur à l’arrêt; -speed est un % de la tension de la batterie en mode boucle ouverte -speed est un % de la vitesse maximale en boucle fermée (régulation: si les frottements ou la charge ì, U ì pour maintenir une même vitesse )
• bool getMotorRunning(tMotor nMotorIndex)
retourne 1 si le moteur est en mouvement ou 0 sinon
Le moteur
La commande en vitesse des moteurs: • void setMotorSyncTime(tMotor Motor1, tMotor Motor2,
long TurnRatio, long TimeMsec, long Speed)
synchronise les 2 moteurs pendant TimeMsec millisecondes ; speed (-100…100%) est la vitesse maximale des moteurs ; TurnRatio influe sur le pourcentage de speed appliqué à chaque moteur :
. 0, les 2 moteurs vont à la même vitesse . 100, le moteur1 reçoit speed et le moteur2 -speed . -100, le moteur1 reçoit -speed et le moteur2 speed . 50, le moteur1 reçoit speed et le moteur2 0
. 25, le moteur 1 reçoit speed et le moteur 2 speed/2 …
Le moteur La commande en position des moteurs: • void setMotorTarget(tMotor Motor,
float position, int speed)
provoque la rotation du moteur jusqu’à la position absolue en degrés du codeur avec la vitesse donnée par speed (-100%...100%)
• void moveMotorTarget(tMotor Motor,
float position, int speed)
provoque la rotation du moteur jusqu’à la position relative (par rapport position courante) en degrés du codeur avec la vitesse donnée par speed • void waitUntilMotorStop(tMotor Motor) attend l’arrêt du moteur avant de continuer (très utile avant de commencer un nouveau mouvement)
Le moteur
La commande en position des moteurs: • void setMotorSyncEncoder(tMotor Motor1, tMotor Motor2,
long TurnRatio, long EncoderCount, long Speed)
synchronise les 2 moteurs jusqu’à atteindre un nombre de pas codeur
EncoderCount ; speed (-100…100%) est la vitesse maximale des moteurs ; TurnRatio influe sur le pourcentage de speed appliqué à chaque moteur :
. 0, les 2 moteurs vont à la même vitesse . 100, le moteur1 reçoit speed et le moteur2 -speed . -100, le moteur1 reçoit -speed et le moteur2 speed . 50, le moteur1 reçoit speed et le moteur2 0
. 25, le moteur 1 reçoit speed et le moteur 2 speed/2
Evitement d’obstacle avec robot tribot task main() {
while(1) { setMotorSpeed(leftMotor,50); setMotorSpeed(rightMotor,50);
if (getUSDistance(sonarSensor)<14)
{setMotorSpeed(leftMotor,0);
setMotorSpeed(rightMotor,0); setMotorSpeed(leftMotor,50);
sleep(700); } }}
Evitement d’obstacle avec robot tribot (en mieux) task main()
{
while(1)
{ setMotorSpeed(leftMotor,50);
setMotorSpeed(rightMotor,50);
while (getUSDistance(sonarSensor)>14);
{setMotorSpeed(leftMotor,0);
setMotorSpeed(rightMotor,0);
moveMotorTarget(leftMotor,360,50); waitUntilMotorStop(leftMotor); }
}}
Iconographie • [techcamp] http://www.techcamp.com.au/?page_id=523 • [Helix84] Vector remaked svg version by user:Helix84 • [encoder]
http://www.electronicproducts.com/Electromechanical_Components/Choosing_a_sensor_to_measure_rotation.aspx
• [philo] http://www.philohome.com/nxtmotor/nxtmotor.htm • [electroiq] http://electroiq.com/blog/2010/11/introduction-to-mems-gyroscopes/ • [escplanta] http://escplantagenet.org/informatique/robotique/ping1.html • [dcmotor] http://www.trainsjouets.webege.com/lesmoteurs/index.html • [dcmodel]
http://robotics.ee.uwa.edu.au/courses/embedded/tutorials/tutorials/tutorial_6/Tutorial_6.htm
• [hbridge] http://www.hassockshog.co.uk/motor_controller_description.htm • Artist Martz 90