Robot humanoïde avec 25 degrés de liberté

Bonjour,

il y a quelques temps je me suis lancé sur ce projet qui hibernait dans un coin de mon cerveau;
le champs d'utilisation des cartes ARDUINO qui est énorme m'a décidé à m'y remettre;
J'ai enfin terminé un chassis qui me semble correct et je débute la programmation mais mes notions de bases sont celles du 68HC11 et datent de 1997...

Pour le moment j'arrive à lire des codes de télécommande IR, commander des servos avec ainsi qu'à jouer des sons wav avec le shield adafruit, j'ai branché un clavier USB directement avec les entrées numériques, je vais essayé la lecture/commande d'un double joystick démonté d'une manette PS2;

les taches qu'il me reste à accomplir sont encore de taille et je pense avoir besoin des conseils éclairés de nos vénérables anciens qui maitrisent avec virtuosité les lignes de code pour des corrections/suggestions ou pourquoi pas un coup de pouce, mais là n'est pas le but du Do It Yourself.

PROJET:

Commander le chassis réalisé (photo) avec une simple télécommande IR pour des séquences préprogrammées,

commander le chassis aves les deux joysticks et le clavier servant à sélectionner la série de 4 servos à commander par les joysticks en incrémentant/décrémentant les angles comme avec des poussoirs mais en plus pratique; un genre d'adressage en fait qui se verrouille par simple appui, je pense utiliser une touche du clavier pour la déselection, ça devrait simplifier les choses; je me vois mal gérer un pupitre de 16 joystiks...

je pense utiliser des accélérometres pour le faire tenir automatiquement debout et éviter les chutes lorsqu'il se déplace ou lève un bras, là est mon plus gros problème pour le moment;

pour simplifier l'utilisation je pense mettre une sous séquence de mise à jour des données envoyées à l'USC (carte de commande de 32 servos par ligne TX/RX) directement sous la LOOP mais je ne sais pas comment lui faire envoyer des chiffres à la place de constantes, je m'explique: la ligne de commande normale est

 Serial.println("#1P2000T200");

servo 1 valeur d'angle 2000 temps de déplacement 200 ms (ça fonctionne bien mais c'est limité...),

Je voudrais faire une sous commande en remplaçant la valeur d'angle et le temps de mouvement par des constantes (ou variables, je m'y perds encore un peu) que je pourrais ajuster par incrémentation/décrémentation en fonction des besoins du style:

 Serial.println("#1P(Angle)T(Temps)");

j'ai mis des parenthèses pour la clarté mais je ne sais pas comment faire pour que les valeurs remplacent les mots, une fois débloqué pour un servo, les autres suivront bien sur.

*******Est-il possible d'envoyer ce code par un port numérique déclaré en sortie?

Je ne sais pas où trouver des référence pour les déplacement angulaire de la marche bipède;

quelqu'un connaitrait-il un logiciel permettant de modéliser en 2D/3D son projet, de le simuler et de le programmer directement en fonction des éléments qui le compose?

ça me simplifirait pas mal le boulot mais existe-t-il?

matériel:

USC32 TOROBOT permettant de commander 32 servos par l'envoi d'une chaine de caractères via le port RX;

2x ARDUINO PRO MINI 5v 16MHZ;
(au cas où pour les tests : 1x ARDUINO MEGA, 1x ARDUINO UNO, 1x ARDUINO NANO)

1x Adafruit Wave Shield

2x accéléromètres 3 axes ADXL345

1x accéléromètre 3 axes Arduino MMA7361 (MMA7260) Accelerometer Sensor Module

2x RF-2400-V03 2.4GHz Wireless Transceiver

1x Wireless Serial 4 Pin Bluetooth RF Transceiver Module

2x NRF905 émetteur/récepteur

quelques modules émetteurs et récepteurs en 433MHZ

un capteur HC-SR04 au cas où;

mais je n'arrive pas encore à faire fonctionner les liaisons sans fil car je ne comprends pas encore comment ils fonctionnent...... :~ :roll_eyes:

les capteurs rendront robot autonomes mais je voudrais garder un accès maître même en mode autonome, pour lui faire faire des tâches pré-programmées lorsqu'il est en mode autonome (style surveillance, interagir avec son environnement...)

dans un premier temps ça sera le mode manuel...

je pense avoir synthétisé le projet, si quelqu'un a des suggestion ou des idées pour m'aider à avance je lui en serai trés reconnaissant

Bonjour

Pour faire

Serial.println("#1P(Angle)T(Temps)");

tu peux faire :

Serial.print("#1P");
Serial.print(Angle);
Serial.print("T");
Serial.println(Temps);

Ou utiliser sprintf() :

char buffer[30]; // a ajuster comme nécessaire
sprintf( buffer, "#1P%dT%d", Angle, Temps );
Serial.println(buffer);

J'ai supposé dans le 2eme cas que Angle et Temps sont des variable de type entier (int).
Si ce sot des flottants, il faut remplacer le %d dans la chaîne de format en %f avec eventuellement des compléments pour régler le nombre de décimales.

Bonjour barbudor,

merci de ta réponse,

effectivement la seconde solution me parait la mieux adaptée car je pense envoyer une chaine de commande des 32 servos à chaques modifications d'angle;

Je confirme, les valeurs d'angle et de temps sont bien des nombres entiers;

j'avais fait un test de la carte avec seulement 4 servos en utilisant ce code:

#include <IRremote.h>
int RECV_PIN = 2;
int codeValue; //les code de la télécommande

IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{
  Serial.begin(9600);            // lancer un port série sur le serial monitor  
  
  irrecv.enableIRIn();          // Démarrer le récepteur

}
void loop()
{ 
  Serial.println(results.value, DEC);

  if (irrecv.decode(&results)) 
  { 
    codeValue = results.value;
    switch (codeValue) 
    {
    case 16716015: // touche 4 de la télécomande
      Serial.println("#1P2000#2P2500#3P600#4P800T200");
      break;

    case 16734885: // touche 6 de la télécommande
 Serial.println("#1P2300#2P1800#3P1600#4P1800T1000");
      break;

    case 16718055: // touche 2 de la télécommande 
Serial.println("#1P1000#2P1000#3P1000#4P2300T800");
      break;

    case 16730805: // touche 8 de la télécommande
Serial.println("#1P600#2P600#3P2000#4P1000T100");
      break;
    } 
    irrecv.resume();
  } 
}

j'utilisais une télécommande IR sur une de mes cartes arduino pro mini reliée à l'USC, ça ne fonctionne pas trop mal mais je voudrais automatisé et simplifier l'envoi à l'USC;

A la place de la commande Serial.println... j'aimerais n'avoir que SEND-USC par exemple et pouvoir changer les angles simplement comme avec l'arduino par une télécommande;

Je le faisais avec ce code où j'avais en plus un relais :

#include <IRremote.h>
#include <Servo.h>

Servo servo1;  // créer un objet d'asservissement pour commander le servo1
Servo servo2; // créer un objet d'asservissement pour commander le servo2
int position1;    // variable pour stocker la position1 d'asservissement
int position2;   //variable pour stocker la position2 d'asservissement
int RECV_PIN = 11;
int RELAY_PIN = 5;
int LED_PIN = 13;
int current = 90; //conserver la trace de la position actuelle du servo
int current1 = 90;
int codeValue; //les code de la télécommande

IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{
  Serial.begin(9600);            // lancer un port série sur le serial monitor  
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
  servo1.attach(7);            // attache le servo sur la broche 7 Ã  l'objet d'asservissement
  servo2.attach(6);          // attache le servo sur la broche 6 Ã  l'objet d'asservissement
  irrecv.enableIRIn();          // Démarrer le récepteur
  servo1.write(current);
  servo2.write(current1);
}
void loop()
{ 
  Serial.println(results.value, DEC);

  if (irrecv.decode(&results)) 
  { 
    codeValue = results.value;
    switch (codeValue) 
    {
    case 16734885: // touche 6 de la télécommande 
      current  +=10;
      if (current > 160) current = 158;
      servo1.write(current);
      break;

    case 16716015: // touche 4 de la télécomande
      current -=10;
      if (current < 22) current = 20;
      servo1.write(current);
      break;

    case 16730805: // touche 8 de la télécommande    
      current1 -=10;
      if (current < 22) current = 20;
      servo2.write(current1);
      break;

    case 16718055: // touche 2 de la télécommande  
      current1 +=10;
      if (current > 160) current = 158;
      servo2.write(current1);
      break;

    case 16726215: // touche 5 de la télécommande RELAY

      {    
        digitalWrite(RELAY_PIN, HIGH);
        {
          digitalWrite(LED_PIN, HIGH);
          delay ( 800 );
          digitalWrite(LED_PIN, LOW);
          delay ( 800 );
          digitalWrite(LED_PIN, HIGH);
        }
      }
      break;

    case 16712445:
      {
        digitalWrite(RELAY_PIN, LOW);
        digitalWrite(LED_PIN, LOW);
      }
      break;    


    } 
    irrecv.resume();
  } 
}

J'avais pensé remodifier ce code pour que la variation d'angle se valide et se poursuive tant que la touche était appuyée mais elle envoyait le code FFFF FFFF suite au premier code et je ne sais pas encore utiliser le buffer donc je l'avais mis un peu de côté.

je pense que le buffer me permettra aussi d'utiliser enfin mes module de dialogue 2.4GHZ mais je n'en suis pas encore là.

Pour le moment je me contenterai de faire bouger le robot même avec un fil à la patte, du moment qu'il ne tombe pas au moindre mouvement...

pour plus de clarté je joins l'implantation des servos et leur référencement.

désolé, mauvaise photo jointe