Aller au contenu


pat92fr

Inscrit(e) (le) 04 août 2020
Déconnecté Dernière activité avril 14 2024 11:28
-----

Messages que j'ai postés

Dans le sujet : 8DOF - Q5 - Mon grand quadrupède

24 août 2023 - 06:39

Pour moi, la longueur du robot est égale ou légèrement supérieure à la somme de la longueur du tibia et du fémur. Du coup, ca donne une indication de la garde au sol que je retiens (un peu supérieure à la longueur du tibia).

 

Ca permet de courir avec cette extension :

Fichier joint  go1web-3a.png   206,38 Ko   13 téléchargement(s)

(désolé pour la pub Uni)

 

Pour le ratio entre la longueur et la largeur, je dirais environ K = 1.5 à 2 (ie. longueur = K x largeur). Comme je n'ai pas d'algorithme de stabilité, je ne sais pas augmenter ce ratio comme certains robots commerciaux et courir avec pieds qui se rapprochent d'une ligne (à l'extrème comme les chats).

Fichier joint  Capture.PNG   520,83 Ko   13 téléchargement(s)


Dans le sujet : 8DOF - Q5 - Mon grand quadrupède

13 août 2023 - 09:32

Pour le reste c'est vrai que le champ d'essais reste vaste et très intéressant. Je rajouterai la forme et la matière du pieds, paramètres qui me semblent importants quand je vois les glissements et les écarts de vitesse suivant la granulométrie des sols.

 

Ce matériaux a une importance parce que les pieds frottent sur le sol en phase de swing. Ca ne devrait pas être la cas. Avec un quadrupède assez rigide et coupleux, on pourrait utiliser un matériau qui donne la meilleure adhérence possible (gomme).


Dans le sujet : 8DOF - Q5 - Mon grand quadrupède

12 août 2023 - 11:17

Bravo Oracid. 2m/s avec un quadrupède XL en Lego, c'était pas gagné !

 

De toutes nos observations, on constate qu'une vitesse angulaire élevée des actionneurs (servo ou autre) aux articulations, notamment hanches/genoux, et une faible inertie des pattes, sont décisives pour obtenir une marche rapide. Réduire la masse totale du robot, et positionner le Cg le plus bas possible, sont aussi des facteurs de réussite (stabilité, accélération). La résistance des matériaux Lego atteint sa limite avec cette version XL, et il serait certainement possible d'aller plus loin avec d'autres matériaux. 

 

Il doit y avoir un gisement de gain de performance dans l'allure du robot. Aujourd'hui, on est limité à une forme très particulière du trot, sans phase de suspension avec des pieds qui peuvent même glisser sur le sol en phase de swing. Si on parvenait à réaliser un véritable trot avec une phase de suspension, les vitesses atteintes seraient intéressantes. Il faudrait non seulement conserver la vitesse de rotation des pates, mais parvenir à augmenter la force d'appui au sol, en fin de phase de stance pour donner l'impulsion nécessaire au "décollage". Il faut un (dos) châssis suffisamment rigide pour que cette impulsion déplace le centre de gravité de robot vers le haut et l'avant, et pas juste déformer le corps du robot au niveau des hanches. 

 

Avec des matériaux très rigides, de bons servos, et un moyen de reproduire des tendons pour absorber les chocs, voire restituer un peu d'énergie et surtout préserver les engrenages des servos....quitte à ce que cela ne fonctionne qu'à une seule vitesse optimisée. Faudrait un peu de temps !


Dans le sujet : 8DOF - Q5 - Mon grand quadrupède

29 juillet 2023 - 05:26

#include <Servo.h>
// Change REFRESH_INTERVAL to 3031 (us) in servo.h

int const pb {A0}; // start button pin

static unsigned long const WALKING_TIME_US {5500000L}; // walking  duration in microseconds
static unsigned long const STRIDE_TIME_US {333333};   // stride duration in microseconds (TO BE ADJUSTED)
static unsigned long const CYCLES_IN_A_STRIDE {STRIDE_TIME_US/REFRESH_INTERVAL};   // number of cycle in a stride (swing+stance)

static unsigned long previous_time_us {0}; // reset 
static unsigned long start_time_us {0}; // reset 
static unsigned long cycle_counter {0}; // reset 

static size_t const SERVO_COUNT {8};
static Servo Srv[SERVO_COUNT];   
enum servo_table { FRLS=0, FRRS, FLLS, FLRS, BRLS, BRRS, BLLS, BLRS};               // Servos table
static int const servo_pin[SERVO_COUNT] {   2,   3,   4,   5,  10,  11,  12,  13};  // PWM pins
static int const servo_min[SERVO_COUNT] { 550, 500, 540, 500, 500, 590, 510, 510};  // all servos values for 0°
static int const servo_max[SERVO_COUNT] {2650,2560,2550,2500,2500,2520,2550,2600};  // all servos values for 180°
static int const servo_ena[SERVO_COUNT] {   1,   1,   1,   1,   1,   1,   1,   1};  // all servos enable/disable

static int servo_position[SERVO_COUNT][CYCLES_IN_A_STRIDE]; // reset

void IK( /***/ )
{
  /***/
}

void setup() {
  pinMode(pb,INPUT_PULLUP); // start/stop/reset button attachment
  for(size_t servo=FRLS; servo<BLRS; ++servo) { // attach all servo
    Srv[servo].attach(servo_pin[servo],servo_min[servo],servo_max[servo]); 
  }
  Serial.begin(9600); // debug port
  Serial.println("Hello world!");
  // pre compute servo positions
    for(size_t cycle=0; cycle<CYCLES_IN_A_STRIDE; ++cycle) { // compute position for each cycle/ A cycle lasts REFRESH_INTERVAL microseconds.
      for(size_t servo=FRLS; servo<BLRS; servo+=2) { // compute position for each servo according servo table
        // TODO : compute foot position (X,Y,Z) based on the current cycle and the current leg
        // TODO : compute HIPS servo position using IK() and previous foot position (X,Y,Z)
        servo_position[servo  ][cycle] = 1234; // xxLS position
        servo_position[servo+1][cycle] = 4567; // xxRS position
    }
  }
  Serial.println("Push Start button when ready...");
  while( digitalRead(pb) );  
  delay(400);
  Serial.println("Start!");
  previous_time_us = micros(); // ready to walk
  start_time_us = micros(); // ready to walk
}

void loop() {
  unsigned long const current_time_us {micros()};

  // stop condition based on time
  if(current_time_us>=start_time_us+WALKING_TIME_US) {
   Serial.println("Stop!");   
   delay(1000);   
   return;
  }

  // execute this at 330Hz
  if(current_time_us>=previous_time_us+REFRESH_INTERVAL) {
    // update servo position
    for(size_t servo=FRLS; servo<BLRS; ++servo) { 
       // play pre computed positions at each cycle for every servo
      if(servo_ena[servo]) Srv[servo].writeMicroseconds(map(servo_position[servo][cycle_counter%CYCLES_IN_A_STRIDE],0,100,servo_min[servo],servo_max[servo])); 
    }
    // next cycle
    ++cycle_counter;
    previous_time_us += REFRESH_INTERVAL;
  }

  // output trace from times to times (every ~3s)
  if(cycle_counter%1000==0) {
    char line[64];
    sprintf(line,"Loop freq.=%0.1f\r\n",(float)(cycle_counter*1000/millis()));
    Serial.println(line);
  }
}

Servo.h risque d'être assez utile pour pilote tes servo. Voila la structure de code à laquelle je pense. Si tu veux l'utiliser, il faudra remettre ton IK() et compléter setup() avec ta facon de calculer la position des servos en fonction des cycles.

 

Un cycle correspond à une impulsion PWM, ca dure donc 3031µs. Pour chaque impulsion, tu prépares au démarrage du robot, la position de tous les servos que tu ranges dans une grosse table appelée servo_position[][].

 

J'ai essayé de coller à ton code, mais il y a un peu de boulot et j'ai pas d'Arduino et de servo pour tester.

 

Bon courage.

Patrick.


Dans le sujet : 8DOF - Q5 - Mon grand quadrupède

29 juillet 2023 - 02:03

Mon nouveau quadrupède marche à 2.5m/s. Un jour ensoleillé, je te propose une course amicale, sur le terrain de ton choix ! Je viendrai avec un magnifique sombrero !  :ignat_02: