[LinuxFocus-icon]
Sommaire  |  Carte  |  Index  |  Recherche

Nouvelles | Archives | Liens | A propos
Cet article est disponible en: English  Castellano  Deutsch  Francais  Nederlands  Portugues  Russian  Turkce  Arabic  

convert to palmConvert to GutenPalm
or to PalmDoc

[Photo des Auteurs]
par Katja et Guido Socher
<katja(at)linuxfocus.org, guido.socher(at)linuxfocus.org>

About the authors:

Katja est l'éditrice Allemande de LinuxFocus. Elle aime Tux, les films et la photographie et la mer. Sa page personnelle est ici.

Guido est fan de Linux de longue date et il l'aime parce qu'il est conçu par des gens honnêtes et ouverts. C'est aussi une des raisons pour laquelle nous l'appelons "open source". Sa page personnelle est linuxfocus.org/~guido.



Traduit en Français par:
John Perr <johnperr(at)linuxfocus.org>

Sommaire:

 

Construire un robot marcheur controllé par Linux

[Illustration]

Résumé:

Dans cet article, nous construisons un petit robot marcheur à six pattes qui peut être contrôlé avec un PC sous Linux en utilisant l'interface parallèle.
D'autres appareils peuvent être pilotés de la même manière par cette interface.

 

Introduction

Les robots nous ont toujours fascinés et nous avons été très excités lorsque nous avons trouvé, il y a quelques temps; un livre sur les robots qui incluait un kit pour construire un petit robot insectoïde appelé Stiquito. Stiquito est un robot un peu spécial car il n'a pas de moteur mais marche grâce à ses pattes faites de nitinol. De cette façon, il progresse en silence comme un véritable insecte. Lors de sa construction, nous avons cependant noté qu'à cause du manque d'adhérence de la surface sur laquelle il marchait, son déplacement était très lent. Heureusement, le livre contenait des descriptions d'autres sortes de robots qui nous ont inspirés pour aboutir à celui qui nous concerne ici.

 

Nitinol

Notre robot n'a pas de moteur et marche parce que ses jambes sont construites et motorisées par le nitinol. Le nitinol est un moteur construit dans un fil d'alliage à mémoire de forme fait de nickel et de titane qui se contracte comme des muscles quand il est chauffé électriquement. Quand le fil conduit le courant, il se chauffe et se rétracte (il revient à sa forme "non étirée"). Une force opposée (corde à piano dans notre cas) est alors nécessaire pour le ramener à sa longueur initiale. S'il est étiré seulement de 3 à 5 pour cent, le fil muscle est très fiable et homogène et peut fonctionner des millions de cycles.


 

Construction du robot

Pour construire le robot nous avons utilisé les pièces suivantes:



[pinces]
Fig 2: pince à becs fins

Vous devriez trouver la plupart des composants dans des magasins de modélisme ou l'on se procure habituellement des pièces pour des petits avions, des voitures radio-commandées etc... Si vous n'en trouvez pas dans votre ville, recherchez l'école d'architecture la plus proche. Comme les étudiants doivent généralement construire des maquettes de maisons et autres bâtiments, vous trouverez sûrement un commerce où il est possible d'acheter des choses comme le tube de laiton très fin.
Lors de l'achat des pinces à becs fins, assurez vous qu'elles ont une face plate, sinon vous n'arriverez pas à plier le fil de nitinol.




[composants] Traduction des termes du dessin:
Holes = Trous
Music Wire = Corde à Piano
(Steel Wire) = (Fil d'acier)
Fig 3: Les principaux composants du robot.  

Construction du corps

Pour le corps vous avez d'abord besoin de trois morceaux de circuit imprimé, un de 6x6 trous et deux de 6x7 trous ainsi que de 4 cm de tube de laiton de 2 mm de diamètre et 3,7 cm de corde à piano.

[Charnière]
Fig 4: Colonne vertébrale et arbre de transmission (Ndt:Solder=Soudure)

Coupez le tube de laiton en morceaux de 8, 17,5 et 8mm comme montré sur le dessin. Cela peut être fait en le roulant d'avant en arrière sous un couteau de cuisine bien aiguisé puis en le tordant. Le tube se cassera à l'endroit du rétrécissement fait par le couteau. Il est important que le tube central soit légèrement plus long que le circuit imprimé de 6x6 trous. Coupez environ 3,7 cm de corde à piano afin qu'elle soit plus longue d'environ 3 mm que l'ensemble des 3 tubes. Passer la corde à piano dans les trois tubes.
Le tube central doit pouvoir tourner alors que les deux autres sont soudés sur la corde à piano.

[souder les 3 pièces du corps] Traduction des termes du dessin:
Middle part moves = La partie centrale est mobile
Holes = Trous
Solder = Soudure
Fig 5: Souder les plaques à l'axe principal
 

Le tube central est ensuite soudé sur le circuit imprimé de 6x6 trous. Assurez-vous qu'il puisse tourner. Les deux autres tubes sont soudés sur les deux autres circuits imprimés.
Prenez ensuite le petit circuit imprimé de 2x7 trous. Il est placé sur la tranche au milieu du tube central. Faire une encoche avec une petite lime ou un cutter et le souder au milieu du tube de laiton et au centre du circuit imprimé comme le montre cette figure:
[Le drapeau]
Fig 6: Ajout du petit circuit imprimé (Ndt:Solder=Soudure)

Ebarbez le tube de laiton de 1 mm et coupez plusieurs morceaux de 4 mm de long. Roulez le tube sur le couteau de cuisine puis courbez-le. Vous avez besoin de 16 de ces cavaliers mais préparez-en quelques uns de rechange.

Comme de nombreux sertissages sont nécessaires, faites des essais avec un peu de nitinol avant de commencer: placer le bout du fil de nitinol dans le tube de laiton très fin (1 mm de diamètre externe) puis écrasez-le avec la pince à becs fins. Cette opération s'appelle un sertissage. Vous aurez besoin d'une pince de bonne qualité car le sertissage des tubes de laiton nécessite une force importante. Vous pouvez aussi décaper les bouts du fil de nitinol avec du papier de verre grain 600 pour garantir de bonnes connexions électriques.

Passons maintenant au fil de nitinol qui servira à monter et descendre les pattes.
[Le pont] Traduction des termes du dessin:
Crimp = Sertissage
Press with Finger = Appuyer avec le doigt
-> Moves 2 mm = -> Bouge de 2 mm
Fig 7: "Le pont"  

Etendez le fil de nitinol comme si vous vouliez construire un pont. Commencez d'un coté, puis en passant le fil de nitinol au travers du trou le plus éloigné à gauche dans le drapeau. Faite un noeud avec le fil de nitinol (afin d'assurer une meilleure connexion électrique) et placez y un sertissage (4 mm de tube de laiton). Passez ensuite un second fil de nitinol symétriquement dans la partie droite du drapeau et aux angles situés à la droite des plaques des extrémités. Chaque fois, faites un noeud avec le fil de nitinol placez y un sertissage et serrez fort (voir la figure 7). Le fil de nitinol doit être tendu mais pas trop. En le touchant du doigt, il doit bouger de 2 à 4 mm. S'il n'est pas assez tendu, ou s'il l'est trop, alors le robot ne marchera pas correctement par la suite. Souder les inserts aux circuits imprimés.
Avant de continuer, vérifiez que cela fonctionne. Connectez une pile de 1,5V AA de chaque coté d'un des fils de nitinol. Quand le fil se contracte, le corps central doit tourner de 10 à 20 degrés. Attention de ne pas connecter la pile plus d'une seconde. Le fil se détruit s'il est trop chauffé.

Les pattes


[Corde à piano pour les pattes]
Fig 8: Pliez le fil

Coupez trois morceaux de corde à piano de 10 cm de long pour les pattes. Pliez 1,5 cm de chaque coté puis soudez-les aux trois corps du robot afin qu'elles soient parallèles entre elles.

[Pattes vue de dessus] TOP VIEW = VUE DE DESSUS
[Pattes vue de dessous] BOTTOM VIEW = VUE DE DESSOUS
SOLDER = SOUDURE
Fig 9, 10: Les pattes sur le robot

Câblez maintenant le fil de nitinol aux six pattes.

[pattes et nitinol] STEEL WIRE = CORDE A PIANO
1 HOLE = 1 TROU
Fig 11: Ajoutez les moteurs

Passez le fil de nitinol à travers un sertisseur depuis le haut et dans un trou du circuit imprimé. La distance par rapport à la corde à piano est de 3 trous. Sertissez-le bien (voir les dessins ci-dessus).
Passez ensuite un sertisseur autour de la corde à piano jusqu'à la courbure du genou. Passez le fil de nitinol au travers et sertissez-le. Nous arrivons à la partie la plus délicate. Tenez le robot avec un petit étau puis fixez et courbez les pattes avec de l'adhésif ou du fil de cuivre. La corde à piano sert de ressort de rappel pour le nitinol. Pour que cela fonctionne le nitinol doit être tendu. La corde à piano doit être tirée d'un trou du circuit imprimé vers le nitinol puis le sertisseur doit être soudé à la patte.
[Le nitinol ne doit pas être trop lâche]
Fig 12: nitinol et corde à piano au même niveau


Assurez-vous que la corde à piano et le nitinol sont au même niveau. Les pattes ne doivent pas se déplacer vers le haut ni le bas quand le nitinol se contracte. La patte doit se déplacer vers l'arrière.

Faire de même avec les cinq autres pattes.
Les pattes, la corde à piano et le tube de laiton au milieu du robot servent de bus de puissance. De ce fait, il doit y avoir continuité électrique entre tous ces éléments. Comme la partie médiane a néanmoins plus de jeu, car elle peut tourner et assure ainsi une moins bonne connection électrique, nous allons corriger cela en entourant 3 cm de fil de cuivre fin de 0.1 mm autour d'un reste de tube de laiton. Cela nous donne un petit enroulement duquel il faut retirer le tube de laiton puis le souder d'un coté à la paire de patte interne et de l'autre à une des paires externes. La forme spiralée de l'enroulement garantit un maximum de flexibilité.

Quand le robot est prêt, vous pouvez souder des morceaux de 0,5 m (ou plus si vous voulez) de fil de cuivre vernis fin de 0.1 mm aux sertisseurs sur la carte, puis souder les sertisseurs du corps au circuit imprimé. Il faudra 9 fils, 6 pour les pattes, 2 pour le mouvement haut/bas et un pour le bus de puissance. Vous pouvez souder l'autre extrémité des fils à un petit connecteur que vous pourrez ensuite raccorder dans une prise correspondante sur le circuit pilote.

 

L'allure

Notre insecte est conçu pour marcher à une allure de tripode. Cela signifie que trois pattes sont sur le sol (2 d'un coté, une de l'autre) pendant que les trois autres sont en l'air. Quand le robot marche, les trois pattes sur le sol se déplacent dans une direction pendant que celles en l'air vont dans l'autre sens.
[L'allure]
Fig 13: L'allure



 

Contrôler le robot avec un ordinateur et Linux

 

Le circuit de l'interface

Ce circuit imprimé vous permet d'utiliser votre PC pour contrôler les moteurs du robot et se branche sur le port parallèle.
Quand nous avons essayé notre programme, nous l'avons d'abord fait avec des diodes électro-luminescentes (LED), et nous avons seulement connecté le robot quand tout marchait correctement, c'est à dire que les LED montraient une allure de marche correcte. Vous devriez faire de même lors de vos essais avec le programme.
Le robot est plutôt gourmand et vous aurez besoin d'un courant de 200 à 250 mA à travers le nitinol pour le contracter. Les fils de nitinol de 3 cm font à peu près 7 Ohms. Démarrez toujours le logiciel d'abord car celui-ci met toutes les sorties à zéro dès le début pour éviter d'abîmer le fil de nitinol. Le bios affecte l'état des sorties du port parallèle aléatoirement. De ce fait, certaines sorties pourraient être à l'état actif et le nitinol pourrait être endommagé si le courant y circule plus longtemps qu'une seconde. Le temps nécessaire au nitinol pour se refroidir doit être 1,5 fois le temps de chauffage.

Le schéma:
[Schéma] Traduction des termes du schéma:

Power Supply = Alimentation
7805 Voltage Regulator = Régulateur 7805

The driver circuit for One leg.= L'interface pour 1 patte
You need this 8 times: = A faire en 8 exemplaires

Nitinol Wire = Fil de Nitinol
Data in = entrée
To computer = Coté ordinateur
Fig 14: Schéma de principe 
Comme vous pouvez le voir sur le schéma ci-dessus, nous utilisons une alimentation stabilisée électroniquement. Cela assure une puissance constante et stable et protège le port parallèle. L'alimentation extérieure peut être n'importe quelle source de courant continu entre 6 et 24V. Le 7805 est un régulateur commun. Il faudra juste faire attention aux deux condensateurs (470uF et 0.1uF) qui sont très proches du 7805 afin de l'empêcher d'osciller, ce qui pourrait le détruire.

L'interface réelle, doit être construite 8 fois. Une pour chaque patte et deux pour l'articulation du robot (mouvement vertical des pattes). Nous utilisons un petit transistor darlington NPN parce que le robot demande beaucoup de courant. Le BC875 ou BC618 peut commuter environ 500mA. La résistance de 47K en entrée garantit qu'un circuit ouvert (par exemple, l'ordinateur n'est pas connecté) est toujours équivalent à "inactif". La tension sur le port parallèle est supérieure à 4V si actif et inférieure à 1V pour l'état "inactif". Le transistor sert seulement d'interrupteur et la résistance de 15 ohm limite le courant et protège les deux pattes du robot et le transistor. La LED donne l'état de l'interface (actif/inactif).

Vous pouvez voir ci-dessous des photos du circuit. Les LED rouges (celles qui sont parallèles aux moteurs du robot sont difficiles à voir car nous avons utilisé des LED transparentes rouges. Les résistances de 15 ohm ont été construites à partir de fil de constantan mais uniquement parce que nous avions une grande quantité de ce fil. Il est plus économique d'acheter des résistances de 2W du commerce.


[Circuit 1] [Circuit 2]
Fig 15: Le circuit



 

L'interface parallèle

Le port parallèle à été conçu pour servir de port de sortie sur un ordinateur personnel auquel on connecte une imprimante. Certains ports parallèles permettent à la fois des entrées et des sorties. Ici nous n'utilisons le port que pour les sorties. Dans un futur article, nous brancherons des capteurs sur le robot et nous utiliserons alors les capacités d'entrées du port parallèle. Bien qu'il y ait 25 broches sur ce port, nous n'en utilisons que 9. Huit sont utilisées comme sorties de données et une autre sert de masse.
Le brochage du port parallèle est le suivant:

SUB-D 25 broches FEMELLE sur le PC.

Broche Nom   Dir   Description
 1  STROBE  [-->] Strobe
 2  D0      [-->] Data Bit 0
 3  D1      [-->] Data Bit 1
 4  D2      [-->] Data Bit 2
 5  D3      [-->] Data Bit 3
 6  D4      [-->] Data Bit 4
 7  D5      [-->] Data Bit 5
 8  D6      [-->] Data Bit 6
 9  D7      [-->] Data Bit 7
 10 ACK     [<--] Acknowledge
 11 BUSY    [<--] Busy
 12 PE      [<--] Paper End
 13 SEL     [<--] Select
 14 AUTOFD  [-->] Autofeed
 15 ERROR   [<--] Error
 16 INIT    [-->] Initialize
 17 SELIN   [-->] Select In
 18 GND     [---] Signal Ground
 19 GND     [---] Signal Ground
 20 GND     [---] Signal Ground
 21 GND     [---] Signal Ground
 22 GND     [---] Signal Ground
 23 GND     [---] Signal Ground
 24 GND     [---] Signal Ground
 25 GND     [---] Signal Ground
Le circuit se connecte à la broche 18 (Masse) et aux broches de données, broches (2-9).

Le port parallèle attend normalement un octet sur les lignes "Data" validé par une impulsion positive sur la ligne "strobe" pour indiquer à l'imprimante que les données sont valides. Nous utilisons directement les lignes de données parce que nous ne voulons pas compliquer inutilement la logique en utilisant la ligne strobe.

 

Le logiciel

Vous pouvez télécharger le logiciel > ici <.

Décompressez-le avec la commande tar zxvf pprobi*.tar.gz. Les instructions d'installation y sont incluses.

Le programme est écrit en C. Avec les touches fléchées et la barre d'espace vous pouvez contrôler le robot: marche avant, droite, gauche ou arrière. Utilisez la barre d'espace ou q (ou x) pour quitter le programme. Au lieu des touches fléchées, vous pouvez aussi utiliser les touches h,j,k,l (comme dans vi) si vous préférez. Les valeurs utilisées pour les mouvements des pattes sont optimales pour notre robot. Chaque robot est différent parce qu'il est difficile d'avoir la même tension du fil de nitinol sur tous les modèles. Votre robot marchera avec le logiciel tel quel, mais toutes les pattes ne bougeront pas forcément de la même manière. Il vous faudra faire des essais pour trouver les valeurs adaptées à votre robot. Faites attention à ne pas surchauffer les pattes de votre robot et qu'elles aient le temps de refroidir.

==== pprobi.c =====
/* vim: set sw=8 ts=8 si : */
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License.
 * See http://www.gnu.org/copyleft/ for details.
 *
 * Written by Katja Socher <[email protected]>
 *         and Guido Socher <[email protected]>
 *
 */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <math.h>
#include <signal.h>

#include "robi.h"

/* ----------- */
static int opt_r=0;
static int fd=0;
/* ----------- */
/* ----------- */
void help()
{
    printf("pprobi -- control software for a walking robot\n\
USAGE: pprobi [-h] [parport-device]\n\
\n\
OPTIONS:\n\
         -h this help\n\
         -r reset the parallel port data pins (all zero) and exit\n\
     \n\
The default device is /dev/parport0 \n\
");
#ifdef VERINFO
    puts(VERINFO);
#endif
exit(0);
}
/* Signal handler: all off then exit */
void offandexit(int code)
{
    robi_setdata(fd,0);
    set_terminal(0);
    exit(0);
}

/* ----------- */
int main(int argc, char **argv)
{
    int state,bpat,alternate;
    char *dev;
    /* The following things are used for getopt: */
    int ch;
        extern char *optarg;
        extern int optind;
        extern int opterr;

    opterr = 0;
    while ((ch = (char)getopt(argc, argv, "hr")) != -1) {
        switch (ch) {
        case 'h':
            help(); /*no break, help does not return */
        case 'r':
            opt_r=1;
            break;
        case '?':
            fprintf(stderr, "serialtemp ERROR: No such option. -h for help.\n");
            exit(1);
        /*no default action for case */
        }
    }
    if (argc-optind < 1){
        /* less than one argument */
        dev="/dev/parport0";
    }else{
        /* the user has provided one argument */
        dev=argv[optind];
    }
    fd=robi_claim(dev); /* robi_claim has its own error checking */
    /* catch signals INT and TERM and switch off all data lines before
     * terminating */
    signal(SIGINT, offandexit);
    signal(SIGTERM, offandexit);

    /* initialize parpprt data lines to zero: */
    robi_setdata(fd,0);
    set_terminal(1); /* set_terminal has its own error handling */
    state=0;
    alternate=0;
    if (opt_r){
        offandexit(1);
    }
        while(1){
        ch=getchoice();
        if (ch!=0) state=ch;
        if (ch == ' '){
            printf("Stop\n");
            robi_setdata(fd,0);
            usleep(500*1000);
        }
        if (ch == 'q'|| ch == 'x'){
            printf("Quit\n");
            break;
        }

        if (state=='l'){
            /*right */
            printf("walking right\n");
            walkright(fd);
        }
        if (state=='h'){
            /*left */
            printf("walking left\n");
            walkleft(fd);
        }
        if (state=='j'){
            printf("walking back\n");
            walkback(fd);
        }
        if (state=='k'){
            if (alternate){
                printf("walking straight on a\n");
                walkstraight_a(fd);
            }else{
                printf("walking straight on b\n");
                walkstraight_b(fd);
            }
            alternate=(alternate +1) %2;
        }

    }
    /* we get here if q was typed */
    set_terminal(0);
    return (0);
}

==== robi.c  =====
/* vim: set sw=8 ts=8 si : */
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License.
 * See http://www.gnu.org/copyleft/ for details.
 *
 * Written by Katja Socher <[email protected]>
 *        and Guido Socher <[email protected]>
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/time.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <linux/ppdev.h>
#include <sys/ioctl.h>
#include <termios.h>
#include "robi.h"


/* like printf but exit the program */
static int die(const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    vprintf(fmt, ap);
    va_end(ap);
    exit(1);
}
/* get one character from stdin
 * Returns non zero if char was read otherwise zero
 * The arrow keys are mapped as follows:
 * <- = h
 * -> = l
 * v = j
 * ^ = k
 */
int getchoice()
{
    int c;
    char s[20];

    if (fgets(s,20,stdin)){
        c=s[0];
        switch (c){
            case 0x1b: /* ESC */
                if (s[1] == 0x5b){
                    /* arrow keys are pressed */
                    switch (s[2]){
                        case 0x41: /*up arrow*/
                            c='k';
                            break;
                        case 0x42: /*down arrow*/
                            c='j';
                            break;
                        case 0x44: /*l arrow*/
                            c='h';
                            break;
                        case 0x43: /*r arrow*/
                            c='l';
                            break;
                        default:
                            c=0;
                    }
                }else{
                    c=0;
                }
                break;
            case ' ':
            case 'h':
            case 'j':
            case 'k':
            case 'l':
            case 'q':
            case 'x':
                break;
            default:
                c=0;
        }
        return(c);
    }
    return(0);
}

/* Set the Terminal to Non Canonical mode with echo off
 * or reset the terminal.
 * USAGE: set_terminal(1) for canonical
 */
int set_terminal(int canonical)
{
    static struct termios originalsettings;
    struct termios newsettings;
    static int origok=0; /* set if originalsettings valid */
    if (canonical){
        /* save original settings and set canonical mode*/
        tcgetattr(fileno(stdin),&originalsettings);
        newsettings=originalsettings;
        newsettings.c_lflag &= ~ICANON;
        newsettings.c_lflag &= ~ECHO;
        newsettings.c_cc[VMIN]=0; /* do not block */
        newsettings.c_cc[VTIME]=1; /* 100 ms */
        if (tcsetattr(fileno(stdin),TCSANOW,&newsettings) !=0){
            die("ERROR: could not set terminal attributes on stdin\n");
        }
        origok=1;
    }else{
        if (origok){
            /* restore settings */
            tcsetattr(fileno(stdin),TCSANOW,&originalsettings);
        }
    }
    return(0);
}

/* open /dev/parportX device and claim it.
 * USAGE: fd=robi_claim("/dev/parport0");
 * The return value is a file descriptor used by other
 * functions such as robi_setdata */
int robi_claim(char *dev)
{
    int fd,i;

    fd = open(dev, O_RDWR );
        if (fd < 0) {
                die("ERROR: cannot open device %s\n",dev);
        }
    i=0;
    /* we need exclusive rights as we do not set the control lines*/
    /*ioctl(fd, PPEXCL, &i)&&
           die("ERROR: request for exclusive rights failed\n");*/
    ioctl(fd, PPCLAIM, &i)&&die("ERROR: could not claim parport\n");
    return(fd);

}
/* Walk left
 */
int walkleft(int fd)
{
    /* first B legs to ground */
    robi_setdata(fd,LEGBD);
    usleep(400 *1000);
    /* all A legs 1 step */
    robi_setdata(fd, LEGB1 | LEGB3 );
    usleep(1100 *1000);

    /* first A legs to ground, cool B*/
    robi_setdata(fd,LEGAD);
    usleep(400 *1000);
    robi_setdata(fd,0);
    usleep(1000 *1000);
    return(0);
}
/* Walk right
 */
int walkright(int fd)
{

    /* first A legs to ground */
    robi_setdata(fd,LEGAD);
    usleep(500 *1000);
    robi_setdata(fd,  LEGA3 | LEGAD);
    usleep(300 *1000);
    /* all A legs 1 step */
    robi_setdata(fd, LEGA1 | LEGA3 );
    usleep(1100 *1000);

    /* first B legs to ground, cool A*/
    robi_setdata(fd,LEGBD);
    usleep(400 *1000);
    robi_setdata(fd,0);
    usleep(1000 *1000);
    return(0);
}
/* Walk with all 3 legs 1 step forward
 */
int walkstraight_a(int fd)
{

    /* first A legs to ground */
    robi_setdata(fd,LEGAD);
    usleep(800 *1000);
    /* all A legs 1 step */
    robi_setdata(fd, LEGA1 | LEGA2 | LEGA3 );
    usleep(1000 *1000);

    /* first B legs to ground, cool A*/
    robi_setdata(fd,LEGBD);
    usleep(500 *1000);
    robi_setdata(fd,0);
    usleep(1200 *1000);
    return(0);
}
/* Walk with all 3 legs 1 step forward
 */
int walkstraight_b(int fd)
{
    /* first B legs to ground */
    robi_setdata(fd,LEGBD);
    usleep(400 *1000);
    /* all B legs 1 step */
    robi_setdata(fd,LEGB1 | LEGB2 | LEGB3);
    usleep(1000 *1000);
    /* A down and cool */
    robi_setdata(fd,LEGAD);
    usleep(800 *1000);
    robi_setdata(fd,0);
    usleep(1200 *1000);
    return(0);
}
/* Walk with all 6 legs 1 step back
 */
int walkback(int fd)
{

    /* first A legs to ground */
    robi_setdata(fd,LEGAD);
    usleep(800 *1000);
    /* all B legs 1 step in the air*/
    robi_setdata(fd, LEGB1 | LEGB2 | LEGB3 );
    usleep(500 *1000);

    /* first B legs to ground, cool A*/
    robi_setdata(fd,LEGBD);
    usleep(500 *1000);
    /* all A legs 1 step in the air*/
    robi_setdata(fd,LEGA1 | LEGA2 | LEGA3);
    usleep(500 *1000);
    /* A down and cool */
    robi_setdata(fd,LEGAD);
    usleep(800 *1000);
    robi_setdata(fd,0);
    usleep(1000 *1000);
    return(0);
}
/*---------*/
/* Write a bit pattern to the data lines
 * USAGE: rc=robi_setdata(fd,bitpat);
 * The return value is 0 on success.
 */
int robi_setdata(int fd,unsigned char bitpat)
{
    int rc;

    rc=ioctl(fd, PPWDATA, &bitpat);
    return(rc);
}

==== robi.h =====
/* vim: set sw=8 ts=8 si et: */
#ifndef H_ROBI
#define H_ROBI 1
#define VERINFO "version 0.2"


/* the first thing you need to do: */
extern int robi_claim(char *dev);

/* write a bit pattern to the data lines of the parallel port: */
extern int robi_setdata(int fd,unsigned char bitpat);

/* input and terminal functions */
extern int set_terminal(int canonical);
extern int getchoice();
extern int walkstraight_a(int fd);
extern int walkstraight_b(int fd);
extern int walkback(int fd);
extern int walkleft(int fd);
extern int walkright(int fd);

/* data pins to legs:
 * A1------=------B1
 *         =
 *         =
 * B2------=------A2
 *         =
 *         =
 * A3------=------B3
 *
 *
 * Pin to set A-legs to ground= AD
 * Pin to set B-legs to ground= BD
 *
 * parallel port    leg name
 * -------------------------
 * data 0           A1
 * data 1           A2
 * data 2           A3
 * data 3           AD
 * data 4           B1
 * data 5           B2
 * data 6           B3
 * data 7           BD
 */
#define LEGA1 1
#define LEGA2 2
#define LEGA3 4
#define LEGAD 8
#define LEGB1 16
#define LEGB2 32
#define LEGB3 64
#define LEGBD 128

#endif


Le logiciel utilise la bibliothèque ppdev issue du noyau 2.4.x (Vous devez avoir un noyau 2.3.x ou 2.4.x. Cela ne marchera pas avec une version plus ancienne). C'est une bibliothèque pour écrire des pilotes utilisateurs pour le port parallèle. Dans les noyaux plus anciens, nous aurions dû écrire un module pour le noyau ou utiliser une méthode moins élégante qui aurait seulement permis au super utilisateur d'exécuter le programme. L'API ppdev utilise le fichier /dev/parport0. En changeant les permissions de ce fichier, vous pouvez contrôler qui est autorisé à utiliser le port parallèle.

Pour compiler ppdev comme un module du noyau, vous devez compiler le module PARPORT en même temps que PPDEV. Voici ce que cela donne dans le fichier .config:

#
# Parallel port support
#
CONFIG_PARPORT=m
CONFIG_PARPORT_PC=m
CONFIG_PARPORT_PC_FIFO=y
# CONFIG_PARPORT_PC_SUPERIO is not set
# CONFIG_PARPORT_AMIGA is not set
# CONFIG_PARPORT_MFC3 is not set
# CONFIG_PARPORT_ATARI is not set
# CONFIG_PARPORT_SUNBPP is not set
CONFIG_PARPORT_OTHER=y
CONFIG_PARPORT_1284=y
#
# Character devices
#
CONFIG_PPDEV=m
#


Le programme initialise d'abord le port parallèle avec la commande ioctl PPCLAIM. Puis il passe le terminal en mode non canonique. Cela permet de récupérer directement les entrées du clavier sans que l'utilisateur ait à taper la touche retour après chaque entrée. Ensuite, il entre dans une boucle où il regarde d'abord s'il y a eu des commandes utilisateur, puis fait marcher le robot en accord avec la commande. Sans action de votre part, le programme fera marcher le robot selon le dernier ordre reçu (par exemple continuer à marcher en avant).
La commande ioctl(fd, PPWDATA, &bitpat); est utilisée pour changer l'état des lignes de données.

Les broches de votre robot doivent être connectées aux sorties du circuit d'interface de la manière suivante:

Pattes:
  A1------=------B1
          =
          =
  B2------=------A2
          =
          =
  A3------=------B3


  Broches des pattes A à la masse=AD
  Broches des pattes B à la masse=BD

Lignes de sorties correspondantes du circuit:
  data 0           A1
  data 1           A2
  data 2           A3
  data 3           AD
  data 4           B1
  data 5           B2
  data 6           B3
  data 7           BD

La ligne Data 0 est la sortie du circuit qui se raccorde à la broche 2 du port parallèle (D0).

Et voici, le robot qui marche:
[Oui, il marche]
Il marche un peu trop vite sur cette animation gif. En réalité il est un peu plus lent à cause du temps nécessaire au refroidissement du nitinol pour qu'il retrouve sa taille initiale.


Nous espérons que vous vous êtes bien amusés en construisant ce robot. Tenez-nous au courant de la construction de votre robot, surtout s'il est construit différemment!

 

Bibliographie

 

Discussion sur cet article

Chaque article possède sa page de discussion. Vous pouvez y soumettre un commentaire ou lire ceux d´autres lecteurs:
 page de discussion 

Site Web maintenu par l´équipe d´édition LinuxFocus
© Katja et Guido Socher, FDL
LinuxFocus.org

Cliquez ici pour signaler une erreur ou envoyer un commentaire à Linuxfocus
Translation information:
en --> -- : Katja et Guido Socher <katja(at)linuxfocus.org, guido.socher(at)linuxfocus.org>
en --> fr: John Perr <johnperr(at)linuxfocus.org>

2002-04-23, generated by lfparser version 2.27