Accueil > Culture > Fablab Ado > Fablab ado > création d’un robot bipède
Arduino
jeudi 19 avril 2018 par
Bonjour,
un petit article pour vous présenter nos réalisations de ce trimestre : des robots bipèdes !
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.
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).
le résultat final est plutôt sympa :
Chaque groupe a créé son robot :
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 !