Programmer son NXT!

Tout ce tutoriel est codé avec le logiciel RobotC pour Lego Mindstorms. Pour plus d'info aller voir: notre tutoriel sur le logiciel RobotCDe plus tout les codes sont sous formes de fonctions permettant une prise en main plus simple.

Le Mouvement

Tout les codes ci dessous sont réalisé avec un robot sur deux roues un moteur controlant celle de droite et un autre celle de gauche. Un exemple de ce type de robotici

Pour faire avancer quelque chose il faut de l'énergie mécanique. Cette énergie est produite grâce à un moteur dans le NXT. Pour qu'il puisse produire cette énergie mécanique il lui faut un courant électrique. C'est ce que nous allons voir ici : comment dire à la brique NXT d'envoyer du courant aux moteurs.

Avancer

Pour qu'un courant circule il faut qu'il y ai une différence de tension entre deux points d'un circuit électrique. Le courant circule toujours du + vers le - donc on peut faire tourner le moteur dans un sens ou dans l'autre selon l'endroit du circuit ou l'on met la tension la plus forte.
Pour faire avancer un moteur vers l'avant il faut lui envoyer un courant positif. Pour faire cela il faut utiliser cette ligne de code:


task main()
{
    motor[motorA] = 60;   
}
                                        

Ici nous faisons tourner le moteur A à 60% de la puissance du moteur du NXT.
Mais ce n'est pas aussi simple ! En effet avec ce code le moteur va recevoir qu'un bref courant puis le programme va s'arreter... Il faut donc lui dire pendant combien de temps tourner. Pour l'instant utilisons cette fonction :


wait1Msec(1000);
                                        

Avec cette ligne en plus notre moteur va tourner à 60 % pendant 1 seconde.
Maintenant le problème c'est que nous n'avons que le moteur A qui tourne alors que nous nous voulons faire avancer notre robot. Pour cela il faut faire tourner les deux moteurs comme ceci :


task main()
{
    motor[motorA] = 60;
    motor[motorB] = 60;
    wait1Msec(1000);  
}
                                        

Mais ce n'est pas la meilleur façon pour faire avancer deux moteurs à la même puissance en même temps. Pour les synchroniser à la même vitesse faîtes comme ci dessous :


task main()
{
    nSyncedMotors = synchAB; //on sychronise les deux moteurs, le moteur A dirige
    nSyncedTurnRatio = 100; //On met les deux moteur a la meme vitesse
    motor[motorA] = 60;
    wait1Msec(1000);  
}
                                        

Maintenant que nous arrivons à déplacer notre robot pendant un certains temps nous allons le faire se déplacer d'une certaine distance. Pour cela il faut attribuer une cible au moteur dirigeant puis laisser les moteurs tourner tant que la cible n'est pas atteinte :


task main()
{
    nSyncedMotors = synchAB; //on sychronise les deux moteurs, le moteur A dirige
    nSyncedTurnRatio = 100; //On met les deux moteur a la meme vitesse
    motor[motorA] = 60;
    nMotorEncoder[motorA] = 0; //On reinitialise l'encodage du moteur
    nMotorEncoderTarget[motorA] = 600; //on definit la valeur cible
    motor[motorA] = 60; //On met la puissance du moteur  60%
  
    while(nMotorRunState[motorA] != runStateIdle)//Tant qu'on  pas atteint la cible le programme rester à ce niveaux la 
    {} 
}
                                        

Nous en avons presque finit avec le déplacement vers l'avant du robot. Mais il nous faut encore dire au moteur de s'arrêter une fois la cible atteinte. Ici il s'arrête certes mais il le fait car le programme s'arrête non parce qu'on le lui à dit ! Cela va poser un problème quand nous verrons des programmes plus compliquer car si on n'arrête pas le moteur il continuera à tourner jusqu'à ce qu'on lui assigne une nouvelle valeur.


task main()
{
    nSyncedMotors = synchAB; //on sychronise les deux moteurs, le moteur A dirige
    nSyncedTurnRatio = 100; //On met les deux moteur a la meme vitesse
    motor[motorA] = 60;
    nMotorEncoder[motorA] = 0; //On reinitialise l'encodage du moteur
    nMotorEncoderTarget[motorA] = 600; //on definit la valeur cible
    motor[motorA] = 60; //On met la puissance du moteur  60%
  
    while(nMotorRunState[motorA] != runStateIdle)//Tant qu'on  pas atteint la cible le programme rester à ce niveaux la 
    {} 

    motor[motorA] = 0;
}
                                        

Et voila votre robot avance avec un code correct ! Le seul problème est que si vous vouliez faire avancer le robot le mettre en pause puis le faire repartir il faudra réécrire le même code des deux cotés de la pause. Nous allons donc nous créer une petite fonction qui prend en paramètre la cible que doit atteindre le moteur pour n'avoir qu'à l'appeler pour faire avancer notre robot. Le code:


void avancer(int tour);

task main()
{
    avancer(600);//On avance avec une cible egale a 600
    wait1Msec(1000); //On fait une pause de 1 seconde
    avancer(1200); On avance avec une cible de 1200
}

void avancer(int tour)//fonction avancer
{
    nSyncedMotors = synchAB; //on sychronise les deux moteurs, le moteur A dirige
    nSyncedTurnRatio = 100; //On met les deux moteur a la meme vitesse
    nMotorEncoder[motorA] = 0; //On reinitialise l'encodage du moteur
    nMotorEncoderTarget[motorA] = tour; //on definit la valeur envoye en parametre comme la cible  atteindre
    motor[motorA] = 60; //On met la puissance du moteur a 60%
  
    while(nMotorRunState[motorA] != runStateIdle)//Tant qu'on  pas atteint la cible on laisse le moteur  60%
    {}
    motor[motorA] = 0;//Une fois la cible atteinte on remet le moteur a 0
}
                                        

Reculer

Si vous avez bien suivi le paragraphe d'avant vous avez déjà compris comment reculer... il suffit en effet de changer cette ligne :


motor[motorA] = 60; //On met la puissance du moteur a 60%
                                        

Par celle ci :


motor[motorA] = -60; //On met la puissance du moteur a 60%
                                        

Ansi le courant est inversé et les moteurs tourneront dans l'autre sens.
Voici la fonction reculer complète:


void reculer(int tour);

task main()
{
    reculer(600);//On avance avec une cible egale a 600
    wait1Msec(1000); //On fait une pause de 1 seconde
    reculer(1200); On avance avec une cible de 1200
}

void reculer(int tour)
{
    nSyncedMotors = synchAB;
    nSyncedTurnRatio = 100;
    nMotorEncoder[motorA] = 0;
    nMotorEncoderTarget[motorA] = tour;
    motor[motorA] = -60;
    while(nMotorRunState[motorA] != runStateIdle)
    {}
    motor[motorA] = 0;
}
                                        

Rotation

Pour tourner nous n'allons pas changer la valeur du courant envoyée au moteur mais nous allons jouer sur les paramètres de synchronisation des moteurs. En effet je vous avais dit que les synchroniser permetait d'avancer droit donc logiquement pour tourner il faut les désynchroniser !

Maintenant la direction de rotation dépend du placement de vos moteurs en effet pour moi le moteur A est celui de droite et le B celui de gauche. Pour tourner à droite je vais donc envoyer plus de puissance au moteur A qu'au moteur B :


nSyncedMotors = synchAB;
nSyncedTurnRatio = 50;
                                        

Si vous changez la valeur de la variable nSyncedTurnRation comme ci-dessus dans un code précédant vous verrez alors votre robot avancer vers la droite.

Pour tourner vers la gauche vous pourriez penser qu'il faut donner une valeur négative à nSyncedTurnRatio mais si vous l'essayer vous verrez que le robot va quand même tourner vers la droite car en mettant un nombre négatif vous allez faire tourner les roues dans deux sens différent et non donner plus de puissance au moteur B.

Nous allons donc faire varier la valeur de nSyncedMotors en mettant le moteur B comme maître :


nSyncedMotors = synchBA;
nSyncedTurnRatio = 50;
                                        

Et voilà votre robot peut maintenant tourner à gauche !

Avant de vous donner les fonctions je vais aussi vous montrer comment faire tourner votre robot sur lui même ce qui peut être utile et plus simple avec un robot 2 roues. Pour cela il faut juste mettre les 2 deux moteurs à la même puissance mais dans 2 sens différents :


nSyncedMotors = synchAB;
nSyncedTurnRatio = -100;
ou pour l'autre sens :
nSyncedMotors = synchBA;
nSyncedTurnRatio = -100;
                                        

Et voila maintenant comme promis les fonctions écrites:


void tournerGauche(int nombreTour);
void tournerDroite(int nombreTour);
void avancerDroite(int nombreTour);
void avancerGauche(int nombreTour);
void reculerGauche(int nombreTour);
void reculerDroite(int nombreTour);

void avancerDroite(int nombreTour)
{
    nSyncedMotors = synchAB;
    nSyncedTurnRatio = 50;
    nMotorEncoder[motorB] = 0;
    nMotorEncoderTarget[motorB] = nombreTour;
    motor[motorB] = 60;

    while()
    {}
    motor[motorB] = 0;
}

void avancerGauche(int nombreTour)
{
    nSyncedMotors = synchBA;
    nSyncedTurnRatio = 50;
    nMotorEncoder[motorB] = 0;
    nMotorEncoderTarget[motorB] = nombreTour;
    motor[motorB] = 60;

    while()
    {}
    motor[motorB] = 0;
}

void reculerGauche(int nombreTour)
{
    nSyncedMotors = synchAB;
    nSyncedTurnRatio = 50;
    nMotorEncoder[motorA] = 0;
    nMotorEncoderTarget[motorA] = nombreTour;
    motor[motorA] = -60;
    while(nMotorRunState[motorA] != runStateIdle)    // While the Touch Sensor is inactive (hasn't been pressed):
    {}
    motor[motorA] = 0;
}

void reculerDroite(int nombreTour)
{
    nSyncedMotors = synchBA;
    nSyncedTurnRatio = 50;
    nMotorEncoder[motorB] = 0;
    nMotorEncoderTarget[motorB] = nombreTour;
    motor[motorB] = -60;
    while(nMotorRunState[motorB] != runStateIdle)    // While the Touch Sensor is inactive (hasn't been pressed):
    {}
    motor[motorB] = 0;
}

void tournerGauche(int nombreTour)
{
    nSyncedMotors = synchAB;
    nSyncedTurnRatio = -100;
    nMotorEncoder[motorA] = 0;
    nMotorEncoderTarget[motorA] = nombreTour;
    motor[motorA] = 60;
    while (nMotorRunState[motorA] != runStateIdle)
    {}
    motor[motorA] = 0;
}

void tournerDroite(int nombreTour)
{
    nSyncedMotors = synchBA;
    nSyncedTurnRatio = -100;
    nMotorEncoder[motorB] = 0;
    nMotorEncoderTarget[motorB] = nombreTour;
    motor[motorB] = 60;
    while (nMotorRunState[motorB] != runStateIdle)
    {}
    motor[motorB] = 0;
}