Patronage Laïque Municipal de la Cavale Blanche

Accueil > Culture > Fablab Ado > Fablab ado > création d’un robot bipède

Fablab ado > création d’un robot bipède

Arduino

jeudi 19 avril 2018 par Antoine

Bonjour,
un petit article pour vous présenter nos réalisations de ce trimestre : des robots bipèdes !

JPEG - 96.6 ko
robot_bipede

Nous sommes partis d’une idée dont les plans sont disponibles sur thingiverse

Pour un robot, nous avons besoin :
6 servos moteurs SG90
1 carte arduino
des câbles
une imprimante 3D
des petites vis et un pistolet à colle
une alimentation (un vieux transformateur 230V-7,5V, 0,4A)
un régulateur de tension (pour avoir du 5V à partir de l’alimentation)

Dans un premier temps, nous avons imprimé les différentes pièces avec nos ultimaker 2Go.

JPEG - 71.6 ko
impressions-3D-robot

Ensuite nous avons testé les moteurs puis assemblé le tout. Attention : la géométrie de départ est essentielle (alignement, afin que les moteurs ne soient pas en butée).

JPEG - 146.7 ko
vue_d_ensemble
JPEG - 202.8 ko
cablage

le résultat final est plutôt sympa :

video robot

Chaque groupe a créé son robot :

JPEG - 111.7 ko
robot2
JPEG - 108.9 ko
robot3
JPEG - 143.9 ko
robot4

et le plus attendu : le code !
le code est à adapter en fonction de chaque robot (câblage / position des servos). Stéphane a réalisé un paramétrage permettant de corriger les positions des moteurs des robots (utilisation du moniteur série de l’IDE arduino, inscrire des - ou des +, jusqu’à être parfaitement aligné) ; la valeur (angle) est ensuite à inscrire dans le réglage des offsets (int offset).

Nous avons utilisé la bibliothèque VarSpeedServo ; disponible sur GitHub

// MoonWalker V1.0 / Stéphane BEURRET - FABLAB manager PLMCB
//
// Servos Tower pro SG90
// Fil marron: GND
// Fil rouge: +5V
// Fil orange: Contrôle en PWM
//
// Arduino uno
// sorties Servos PWM 3,5,6 et 9,10,11
//

/*
Quelques informations et définitions :
attach(pin )  - Attaches a servo motor to an i/o pin.
attach(pin, min, max  ) - Attaches to a pin setting min and max values in microseconds
default min is 544, max is 2400  

write(value)     - Sets the servo angle in degrees.  (invalid angle that is valid as pulse in microseconds is treated as microseconds)
write(value, speed) - speed varies the speed of the move to new position 0=full speed, 1-255 slower to faster
write(value, speed, wait) - wait is a boolean that, if true, causes the function call to block until move is complete

writeMicroseconds() - Sets the servo pulse width in microseconds
read()      - Gets the last written servo pulse width as an angle between 0 and 180.
readMicroseconds()  - Gets the last written servo pulse width in microseconds. (was read_us() in first release)
attached()  - Returns true if there is a servo attached.
detach()    - Stops an attached servos from pulsing its i/o pin.

slowmove(value, speed) - The same as write(value, speed), retained for compatibility with Korman's version

stop() - stops the servo at the current position

sequencePlay(sequence, sequencePositions); // play a looping sequence starting at position 0
sequencePlay(sequence, sequencePositions, loop, startPosition); // play sequence with number of positions, loop if true, start at position
sequenceStop(); // stop sequence at current position
wait(); // wait for movement to finish
isMoving()  // return true if servo is still moving
*/


#define pied_g_pin      3
#define genou_g_pin     5
#define hanche_g_pin    6
#define pied_d_pin      9
#define genou_d_pin     10
#define hanche_d_pin    11

#define interval_update 300 // en ms

#include <VarSpeedServo.h>

VarSpeedServo myservo;  // create servo object to control a servo
                       // a maximum of eight servo objects can be created  
class Articulation
{
   VarSpeedServo servo; // the servo
   int offset_servo;
   int updateInterval; // interval between updates
   unsigned long lastUpdate; // last update of position
public:
   Articulation(int interval, int offset)
   {
       updateInterval = interval;
       offset_servo=offset;
   }
   void Attach(int pin)
   {
       servo.attach(pin);
   }
   void Detach()
   {
       servo.detach();
   }
   void Move(int pos, int vitesse)
   {
     servo.write(offset_servo+pos, vitesse);
   /*    if((millis() - lastUpdate) > updateInterval) // time to update
       {
           lastUpdate = millis();
           servo.write(offset_servo+pos, vitesse);
           //Serial.println("offset_servo="+String(offset_servo)+"   angle="+String(pos));
       }
   */
   }
};

int servo_speed=30;
int offset_pied_g=90+8;
int offset_genou_g=90-8;
int offset_hanche_g=90-14;
int offset_pied_d=90-9;
int offset_genou_d=90+6;
int offset_hanche_d=90-8;

Articulation pied_g(interval_update, offset_pied_g);      // servo pied gauche
Articulation genou_g(interval_update, offset_genou_g);     // servo genou gauche
Articulation hanche_g(interval_update, offset_hanche_g);    // servo hanche gauche
Articulation pied_d(interval_update, offset_pied_d);      // servo pied droit
Articulation genou_d(interval_update, offset_genou_d);     // servo genou droit
Articulation hanche_d(interval_update, offset_hanche_d);    // servo hanche droit

int angle_pied_g=0;
int angle_genou_g=0;
int angle_hanche_g=0;
int angle_pied_d=0;
int angle_genou_d=0;
int angle_hanche_d=0;

int angle=10;

void calibration(int ii)
{
  pied_g.Move(ii, servo_speed);  
  genou_g.Move(ii, servo_speed);  
  hanche_g.Move(ii, servo_speed);
  pied_d.Move(ii, servo_speed);    
  genou_d.Move(ii, servo_speed);  
  hanche_d.Move(ii, servo_speed);  
}

void init_position()
{
  pied_g.Move(0, servo_speed);
  genou_g.Move(0, servo_speed);  
  hanche_g.Move(0, servo_speed);
  pied_d.Move(0, servo_speed);
  genou_d.Move(0, servo_speed);  
  hanche_d.Move(0, servo_speed);
}

void appui(int angle)
{
 pied_d.Move(angle, servo_speed);
 pied_g.Move(angle, servo_speed);
}


void plier_jambe_g(int angle)
{
  //pied_g.Move(-angle*1.1, servo_speed);
  genou_g.Move(angle, servo_speed);
  hanche_g.Move(angle, servo_speed);
}
void plier_jambe_d(int angle)
{
  //pied_d.Move(-angle*1.1, servo_speed);
  genou_d.Move(-angle, servo_speed);  
  hanche_d.Move(-angle, servo_speed);
}

void avance_g(int angle)
{
 hanche_g.Move(-angle, servo_speed);
 genou_g.Move(angle, servo_speed);
}

void avance_d(int angle)
{
 hanche_d.Move(-angle, servo_speed);
 genou_d.Move(angle, servo_speed);
}


void test_walk()
{
int tempo=400;
int pas=12;

  appui(-12);
   plier_jambe_g(pas);
   plier_jambe_d(-pas);
  Serial.println("appui gauche");
  delay(tempo);

  appui(12);
   plier_jambe_g(-pas);
   plier_jambe_d(pas);
  Serial.println("appui droit");
  delay(tempo);
 
 // init_position();
 // Serial.println("init");
 // delay(tempo);
}


void setup()
{
 Serial.begin(9600);
 pied_g.Attach(pied_g_pin);
 genou_g.Attach(genou_g_pin);
 hanche_g.Attach(hanche_g_pin);
 pied_d.Attach(pied_d_pin);
 genou_d.Attach(genou_d_pin);
 hanche_d.Attach(hanche_d_pin);
 delay(700);
 init_position();
 //plier_jambe_g(20);
 //plier_jambe_d(20);
}

void loop()
{
char car;
int ii;
car=Serial.read();
if (car=='+')
  {
  angle=angle+1;
  Serial.println("angle="+String(angle));
  calibration(angle);
  }
else if (car=='-')
  {
  angle=angle-1;
  Serial.println("angle="+String(angle));
  calibration(angle);
  }
else if (car=='P')
  {
   plier_jambe_g(20);
   plier_jambe_d(20);
  }
else if (car=='p')
  {
   plier_jambe_g(20);
   plier_jambe_d(-20);
  }  
else if (car=='D')
  {
   plier_jambe_g(0);
   plier_jambe_d(0);
  }
else if (car=='g')
  {
   appui(-15);
   plier_jambe_g(20);
   plier_jambe_d(-20);    
  }
else if (car=='d')
  {
   appui(15);
   plier_jambe_g(-20);
   plier_jambe_d(20);
  }
else if (car=='r')
  {
   init_position();
  }
else if (car=='t')
  {
   for (ii=0;ii<10;ii++)
      test_walk();
   init_position();
  }  
}

pour tester la marche : taper t (puis entrée) dans le moniteur série ;-)

A vous de jouer !


| Plan du site | Mentions légales | Suivre la vie du site RSS 2.0 | Haut de page | SPIP | ScolaSPIP
Patronage Laïque Municipal de la Cavale Blanche (Patronage Laïque Municipal de la Cavale Blanche)