Youpi, testons les moteurs !

 30 décembre 2009  Bricolage  2 commentaires

J’avais longuement expliqué dans cet article les étapes de fabrication d’un câble parallèle pour relier le robot Youpi à un PC standard.

Aujourd’hui je vais comme promis diffuser les quelques lignes de code permettant de tester l’ensemble des moteurs. Le programme est grandement inspiré de celui que l’on peut trouver sur le site du BTS-IRIS de Niort.

C’est un programme développé à la va-vite en C. Il pourra servir de base pour tous ceux qui comme moi souhaitent vérifier que tous les moteurs sont en bon état de fonctionnement.

Le code

robotest.c :

/*
 Youpi Robot Test program
 ------------------------

 This program has to be run as root
 or with sufficient credentials (suid...)
*/

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/io.h>

// Change this to your parallel port
#define LPT 0x378

// Defines the byte type
typedef unsigned char byte;

/*
 This functions writes a byte to the parallel port
 Do not use any other way to do it as the robot needs to pause
 between each instruction.
*/
void writelpt(byte b) {
	int tempo = 1500;
	outb(b, LPT);
	usleep(tempo);
}

/*
 This is the main function
*/
int main() {

	//Variables
	int i,j;
	int steps = 600;

	//Welcome message
	printf("*** YOUPI ROBOT TEST PROGRAM ***\n");

	//Tries to access parallel port
	if(ioperm(LPT, 1, 1) != 0) {
		perror("ioperm");
		return 1;
	}

	//Initializes the robot
	printf(" * Initialization\n");
	writelpt(0x47);
	writelpt(0x00);

	//Orders earch motor to rotate
	for(j=0; j<6; j++) {
		printf(" * Test of motor %d\n", j);

		//...into one direction
		writelpt(0x80);
		writelpt(0x00);
		for(i=0; i<steps; i++) {
			writelpt(0x40+j);
			writelpt(0x00+j);
		}

		//...into the opposite direction
		writelpt(0xBF);
		writelpt(0x3F);
		for(i=0; i<steps; i++) {
			writelpt(0x40+j);
			writelpt(0x00+j);
		}
	}

	return 0;
}

Et le Makefile qui va avec :

CC=gcc
CFLAGS=-W -Wall -O

all: robotest

robotest: robotest.c
	$(CC) $(CFLAGS) -o $@ $<

clean:
	rm robotest

Quelques explications

Le manuel indique une vitesse de rotation maximale de 40°/s pour tous les moteurs, avec une résolution maximale de 0.03° par 1/2 pas. Chaque 1/2 pas est effectué grâce à l’envoi de 2 instructions par le port parallèle. Pour faire avancer le robot à cette vitesse maximale, il est nécessaire d’espacer chaque instruction d’un temps T en secondes, calculé ci-dessous :

Il faut donc espacer chaque instruction de 1500 µs, ce qui explique les 1500 à la ligne 27 du code. Descendre en dessous de cette limite est susceptible de provoquer des catastrophes inconnues, donc si vous essayez, cela sera à vos risques et périls.

Bugs connus

Avec un sommeil de 1500 µs entre chaque instruction, le programme devrait théoriquement être terminé en approximativement 2+6*(2+600*2)*2*0.0015 = 22 secondes, en négligeant le temps nécessaires aux autres instructions. Hors j’obtiens en moyenne un temps d’exécution à 58 secondes.

Ce phénomène est expliqué en partie par le paragraphe suivant, tiré de la page man 3 de usleep :

La période de sommeil peut être allongée par  la  charge  système, par le temps passé à traiter l’appel de fonction, ou par la granularité des temporisations système.

En résumé, lors de mon test, la vitesse de rotation de chaque moteur n’est pour le moment pas optimale. J’avais fait d’autres essais en réduisant significativement cette temporisation à quelques µs, ou en utilisant nanosleep afin d’avoir une granularité plus fine, mais le temps d’exécution total n’est jamais descendu en dessous de ces 58 secondes. Je ne sais pas encore comment optimiser cette vitesse, cela fait appel à des notions d’architecture système et de programmation temps réel qui me manquent à l’heure actuelle. Dans tous les cas, même si la vitesse est à l’heure actuelle bridée, le programme est néanmoins capable de démontrer le fonctionnement correct de chaque moteur.

Informations complémentaires

J’en profite pour placer un rappel : au lieu de me contacter personnellement pour me demander de l’aide à propos de ce robot, merci d’effectuer cette démarche en laissant un commentaire sur ce site afin que les questions et réponses profitent à tout le monde.

NB : vous pourrez maintenant trouver en un seul clic tous les articles de ce site relatifs au robot Youpi grâce au tag Youpi.

 Tags: , , ,

2 commentaires pour “Youpi, testons les moteurs !”

  1. chocho

    Hey, attention, je raconte peut être pas mal de conneries, mais j’ai envie de balancer mes idées, on sait jamais si ca peux t’aider, tu y a déjà sans doute pensé, mais j’ai vraiment envie de savoir ce que tu vas faire de ce youpi ! :)

    Tu ne peux rien lire depuis le robot ? Genre sa position ?

    Que se passe t il si tu fais

    while (position_actuelle != position_a_atteindre) {
    writelpt(déplace_toi)
    position actuelle = readlpt(ou_es_tu_petit_robot)
    }

    ou alors

    nb_pas_a_faire = position_voulue – position_actuelle
    for (i=0;i<nb_pas_a_faire;i++) {
    writelpt(deplace_toi)
    }

    De mémoire de mes TP de premier cycle, on gros on leur disait vitesse maximale jusqu'à une position proche, puis vitesse lente pour arriver précisément la ou on voulait, au demi-pas près.

    Bref, pour optimiser ta relation avec ce robot, cherche ce que tu peux apprendre de lui, ce qu'il balance sur son port parallèle quoi :)

  2. AlphaK

    j’ai vraiment envie de savoir ce que tu vas faire de ce youpi

    Moi aussi, j’aimerais tellement le savoir :)

    Tout d’abord merci pour tes idées.
    Je n’ai jamais essayé de lire le contenu du port parallèle. J’ai la vague impression que si je le fais, le contenu sera identique à celui que j’ai envoyé… J’essaierai à tout hasard, ça ne coûte rien :)

    Je m’explique : le youpi possède *en option* 6 capteurs de position qu’il est possible de lire (cool !). Je ne sais pas si le mien en est équipé, à priori non. Ces informations sont lisibles, si j’en crois la documentation en ma possession, sur des broches différentes de celles utilisées pour envoyer les commandes. Ce qui veut dire que si je cherche à lire l’info sur le même port parallèle, je vais probablement devoir l’adapter pour « fusionner » les signaux d’entrée et de sortie sur les mêmes broches côté PC, tout en protégeant le robot et le PC des court-circuits. Une simple paire de diodes par broche suffira probablement à protéger le robot, mais pas le PC. On commence à dépasser mes compétences en électronique…

    Autrement, je peux aussi conserver le montage actuel, et lire les informations des capteurs avec une autre source dans un premier temps (un oscillo par exemple). Le problème, c’est que le manuel d’origine ne détaille absolument pas comment interpréter l’information donnée par les capteurs. Il semble qu’il s’agisse juste d’une information binaire pour prévenir un mouvement hors-limites. L’information ne serait donc pas très pertinente en dehors de aspect didactique :)

    En ce qui me concerne, je comptais surtout, dans un programme de haut niveau, laisser la possibilité de calibrer la position de chaque bras du robot, laisser le programme mémoriser la position de chaque moteur tout au long de l’exécution, puis revenir en position calibrée au final (afin de passer optionnellement cette étape à la prochaine exécution). Compte tenu de la précision des moteurs, je pense que c’est une option réaliste. Il n’existe malheureusement pas de notion de vitesse par axe, la vitesse ne pouvant être gérée que par le temps d’espacement des instructions.

    Je pense que tu as dû travailler avec des robots plus récents que le mien ;)

Laisser un commentaire