Aller au contenu


Sandro

Inscrit(e) (le) 30 déc. 2013
Déconnecté Dernière activité aujourd'hui, 13:38
*****

#111960 FourBarQuad525 - Toujours plus rapide

Posté par Sandro - 06 décembre 2020 - 12:07

@Patrick : pour le trie, sur la version "naive", ça vaut le coup. Pour la V2, je suis pas sur si c'est encore le cas.

@Patrick : ton second message, j'ai pas compris, en particulier "et sur It."

 

 

Sinon, voici la V2, qui devrait être utilisable :


//équivalences pin/port
//  2   PD2
//  3   PD3
//  4   PD4
//  5   PD5
//  6   PD6
//  7   PD7
//  8   PB0
//  9   PB1

//octets avec un 0 à l'endroit correspondant à un pin dans les registres et 1 ailleurs
#define ZERO_DU_PIN_2 B11111011
#define ZERO_DU_PIN_3 B11110111
#define ZERO_DU_PIN_4 B11101111
#define ZERO_DU_PIN_5 B11011111
#define ZERO_DU_PIN_6 B10111111
#define ZERO_DU_PIN_7 B01111111
#define ZERO_DU_PIN_8 B11111110
#define ZERO_DU_PIN_9 B11111101

//nom du pot correspondant à chaque pin
#define PORT_DE_PIN_2 PORTD
#define PORT_DE_PIN_3 PORTD
#define PORT_DE_PIN_4 PORTD
#define PORT_DE_PIN_5 PORTD
#define PORT_DE_PIN_6 PORTD
#define PORT_DE_PIN_7 PORTD
#define PORT_DE_PIN_8 PORTB
#define PORT_DE_PIN_9 PORTB


#define PERIODE_US 20000  //période

uint16_t duree_pulse_us[10]={0,0,1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700};   //position initiale

uint16_t duree_pulse_us_min[10]={0,0,1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000};
uint16_t duree_pulse_us_max[10]={0,0,2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000};
int angle_min[10]={0,0,0, 0, 0, 0, 0, 0, 0, 0};
int angle_max[10]={0,0,180, 180, 180, 180, 180, 180, 180, 180};

void envoyer_pulse()
{
  unsigned long start_time=micros();
  //mise à 1 de tous les pins
  PORTD |= B11111100; //mise à 1 des pins 2 à 7 du port D (ie pins 2 à 7 de l'arduino)
  PORTB |= B00000011; //mise à 1 des pins 0à 1 du port B (ie pins 8 et 9 de l'arduino)
  
  while( (PORTD & 0B11111100) | (PORTB & 0B00000011) )  //tant qu'au moins un des pins est à 1
  {
    unsigned long duree_actuelle_du_pulse=micros()-start_time;  //durée écoulée depuis le début du pulse
    if(duree_actuelle_du_pulse>=duree_pulse_us[2])
      PORT_DE_PIN_2 &= ZERO_DU_PIN_2;

    if(duree_actuelle_du_pulse>=duree_pulse_us[3])
      PORT_DE_PIN_3 &= ZERO_DU_PIN_3;
      
    if(duree_actuelle_du_pulse>=duree_pulse_us[4])
      PORT_DE_PIN_4 &= ZERO_DU_PIN_4;

    if(duree_actuelle_du_pulse>=duree_pulse_us[5])
      PORT_DE_PIN_5 &= ZERO_DU_PIN_5;

    if(duree_actuelle_du_pulse>=duree_pulse_us[6])
      PORT_DE_PIN_6 &= ZERO_DU_PIN_6;

    if(duree_actuelle_du_pulse>=duree_pulse_us[7])
      PORT_DE_PIN_7 &= ZERO_DU_PIN_7;

    if(duree_actuelle_du_pulse>=duree_pulse_us[8])
      PORT_DE_PIN_8 &= ZERO_DU_PIN_8;

    if(duree_actuelle_du_pulse>=duree_pulse_us[9])
      PORT_DE_PIN_8 &= ZERO_DU_PIN_9;
  }
}

void set_position_degrees(byte pin, int angle_deg)
{
  uint16_t duree_us=map(angle_deg, angle_min[pin], angle_max[pin], duree_pulse_us_min[pin], duree_pulse_us_max[pin]);
  duree_pulse_us[pin]=duree_us;
}

void setup() {
  Serial.begin(115200);
  for(int i=2;i<=9;i++)
  {
    pinMode(i,OUTPUT);
  }
  Serial.println("Hello");
}

int c=0;

void loop() {
  c++;
  unsigned long start_time=micros();
  envoyer_pulse();
  unsigned long duration=micros()-start_time;
  Serial.println(duration);

  /*//faire ici les calculs pour la nouvelle position des servos (position en µs de pulse, pas en degrés)
  duree_pulse_us[2]=1500+((c/100)%2)*300;
  duree_pulse_us[3]=1500+((c/100)%2)*300;
  duree_pulse_us[4]=1500+((c/100)%2)*300;
  duree_pulse_us[5]=1500+((c/100)%2)*300;
  duree_pulse_us[6]=1500+((c/100)%2)*300;
  duree_pulse_us[7]=1500+((c/100)%2)*300;
  duree_pulse_us[8]=1500+((c/100)%2)*300;
  duree_pulse_us[9]=1500;*/

  //variante
  set_position_degrees(2,0);
  set_position_degrees(3,20);
  set_position_degrees(4,40);
  set_position_degrees(5,60);
  set_position_degrees(6,90);
  set_position_degrees(7,120);
  set_position_degrees(8,160);
  set_position_degrees(9,180);

  //attendre la fin de la période
  while(micros()-start_time<PERIODE_US)
  {
    //ne rien faire
  }
}

Nouvautés :

1) le code est beaucoup plus optimisé : l'écart entre le traitement du premier et du dernier servo est de 7*11 cycles d'horloges (11 cycles par servo), soit 4.8µs, ce qui correspond à 0.8°. La fluctuation est encore bien plus faible (1 cycle d'horloge par servo ayant fini son pulse), soit au maximum 7 cycles d'horloges de fluctuation, soit 0.43ms, soit 0.08°

La plus forte cause de fluctuation est donc la fonction micros, qui a une résolution de 4µs, soit 0.7° de fluctuation sur les angles des servos.

En pratique, on ne remarque pas les fluctuations à l'oeil nu
2) renumérotation des servos : maintenant chaque servo correspon au pin (il y a donc 2 emplacements "vides" dans les tableaux, correspondant aux pins 0 et 1 qui ne sont pas utilisés)

3) il y a maintenant une fonction pour donner la consigne en degrés (il y a des tableaux en début du programme pour ajuster les intervales d'angles et les durées en µs correspondantes : ça peut servir pour corriger les offsets des moteurs, ainsi que pour définir une plage angulaire de notre choix (par exemple -90° à +90°). NB : il n'y a aucune sécurité pour les valeurs hors intervalle.

 

@Oracid, je penses que tu peux commencer à intégrer ton code sur cette base si tu en as envie

 

 

EDIT : sur mon servo de test, je peux mettre PERIODE_US aussi petit que je veux, ça a l'air de toujours marcher correctement (nb : il faut quand même laisser PERIODE_US assez grand pour pouvoir réaliser la période souhaitée, sinon la période n'est plus respectée (mais mon servo conserve quand même la position)




#111957 FourBarQuad525 - Toujours plus rapide

Posté par Sandro - 05 décembre 2020 - 10:01

@Patrick : pour la librarie dont tu donnes le lien, elle permet en effet d'utiliser les timers hardware pour commander directement les servos sur l'arduino mega (du coup, pas besoin de re-écrire ce code nous même si on passe à une méga miniature)

 

 

Sinon, voici un premier jet de code pour contrôler 8 servos avec les pulses en simultanés, et garantir qu'une nouvelle consigne sera toujours prise en compte en même temps sur tous les servos :

#define PERIODE_US 20000

uint16_t duree_pulse_us[8]={1700, 1700, 1700, 1700, 1700, 1700, 1700, 1800};
byte servo_pins[8]={2, 3, 4, 5, 6, 7, 8, 9};
bool servo_etat[8]={0, 0, 0, 0, 0, 0, 0, 0};  //état du pin (0 ou 1)

void envoyer_pulse()
{
  uint8_t nbr_servos_restant=8;
  
  for(int i=0;i<8;i++)
  {
    servo_etat[i]=1;  //on s'aprète à mettre à 1 les pins
  }
  
  unsigned long start_time=micros();
  for(int i=0;i<8;i++)
  {
    digitalWrite(servo_pins[i],1);  //on active tous les pins : on commence le pulse
  }
  unsigned long test_time1=micros();
  while(nbr_servos_restant)
  {
    unsigned long duree_actuelle_du_pulse=micros()-start_time;  //durée écoulée depuis le début du pulse
    for(int i=0;i<8;i++)
    {
      if(duree_actuelle_du_pulse>=duree_pulse_us[i] && servo_etat[i]) //si la durée du pulse est écoulée, mais que le pin est encore actif) : il faut le mettre à 0  
      {
        digitalWrite(servo_pins[i],0);
        servo_etat[i]=0;
        nbr_servos_restant--;
      }
    }
  }
}

void setup() {
  Serial.begin(115200);
  for(int i=0;i<8;i++)
  {
    pinMode(servo_pins[i],OUTPUT);
  }
  Serial.println("Hello");
}

int c=0;

void loop() {
  c++;
  unsigned long start_time=micros();
  envoyer_pulse();
  unsigned long duration=micros()-start_time;
  Serial.println(duration);

  //faire ici les calculs pour la nouvelle position des servos (position en µs de pulse, pas en degrés)
  duree_pulse_us[0]=1500+((c/100)%2)*300;
  duree_pulse_us[1]=1500+((c/100)%2)*300;
  duree_pulse_us[2]=1500+((c/100)%2)*300;
  duree_pulse_us[3]=1500+((c/100)%2)*300;
  duree_pulse_us[4]=1500+((c/100)%2)*300;
  duree_pulse_us[5]=1500+((c/100)%2)*300;
  duree_pulse_us[6]=1500+((c/100)%2)*300;
  duree_pulse_us[7]=1500;

  //attendre la fin de la période
  while(micros()-start_time<PERIODE_US)
  {
    //ne rien faire
  }
}

A noter que ce code à pour l'instant plusieurs inconvénients :

- on utilise directement les durées en micro-secondes des pulses et pas les positions angulaires plus pratiques (en gros, on n'utilise que writeMicroseconds de la librairie servo et pas write). C'est pas dur a ajouter, mais c'est pas encore fait

- bien plus gros : par l'algo même, si plusieurs servos on des durées de pulses très proches (voir identiques), il y a aura une erreur sur les "derniers" servos à demander cette durée de pulse (c'est bien visible avec le choix des calculs dans le loop du programme de test). Actuellement, dans le pire des cas (tous les servos à la même position), j'obtiens une erreur max de 52µs, soit environ 9.3°. Ce problème ne pourra jamais être totalement éliminé, mais peut être fortement réduit en écrivant un code plus optimisé (ce que j'ai volontiers pas fait dans la première version pour tester le principe rapidement et pour avoir un code facile à comprendre)

 

NB : dans ce code, la fonction envoyer_pulse est bloquante, mais elle dure moins de 0.1ms de plus que le pulse le plus long

 

 

Du coup, j’attaque une V2, en optimisant le code pour améliorer la précision




#111952 FourBarQuad525 - Toujours plus rapide

Posté par Sandro - 05 décembre 2020 - 08:22

Je pensais que la bibliothèque servo.h générait les impulsions "en même temps", et les arrêtait au fur et à mesure, mais c'est pas ça. En lisant le code source, je pense que Ptarick a raison : c'est un pulse après l'autre.

Pour l'arduino Uno, c'est bien un seul timer (timer 0) qui sert.

Pour un arduino mega, il y a jusqu'à 4 timers qui servent : le premier sert pour les 12 premiers servos, le second pour les 12 suivants,... Du coup, à priori, on peut exécuter 4 impulsions en même temps, à condition de faire croire à la bibliothèque qu'il y a d'autres servos entre. Si on déclare ces servos suplémentaires avec writeMicroseconds(0), on peut à priori avoir seulement l'exécution de 2 servos par timer, soit 5ms.

Si tu veux un peu plus petit que la vrai Méga, il y a un clone plus petit sur la boutique : https://www.robot-ma...60-pro-312.html

 

Pour VarSpeedServo, à première vue, je dirais que ça n'apporte pas grand chose ici (on peut fixer la vitesse du servo, mais vu qu'il on essaye d'aller au plus vite, je ne suis pas sur que ce soit très pertinent).

 

 

Après dîner, je vais voir si j'arrives à faire un code qui se passe de la librarie servo et qui fait tous les pulses en simultané (au prix d'être bloquant pendant 2.5ms)




#111945 FourBarQuad525 - Toujours plus rapide

Posté par Sandro - 05 décembre 2020 - 03:54

Du coup, je suggère qu'on fixe une fois pour toute la "période" (speed) :

- soit un petit peu plus que 20ms, par exemple 21ms

- soit 25ms : c'est la plus petite valeur qui permette un nombre entier de consignes par seconde (40) tout en restant >20ms

- soit on expérimente avec le define qu'a trouvé Patrick, pour trouver jusqu'à quelle fréquence on peut commander les servos en modifiant les defines. D'après le lien suivant, certain servos peuvent descendre jusqu'à moins de 3ms : http://techniquemodelisme.free.fr/Modelisme/servomoteurs.htm

 

Une fois la fréquence d'asservissement fixée, alors on aura un seul paramètre à changer pour expérimenter : la trajectoire (bon, une trajectoire, c'est plein de paramètres)




#111941 FourBarQuad525 - Toujours plus rapide

Posté par Sandro - 05 décembre 2020 - 02:22

Bonjour,

j'ai un peu creusé la question (sur un arduino Uno, mais ça ne devrait absolument rien changer (même microcontroleur, même fréquence)).

 

- les servos utilisent tous le même timer : timer1, le seul timer 16 bits (un timer 8 bits ne suffirait pas pour avoir 180 valeurs sur une petite partie de la période totale (sauf à rajouter un compteur d'overflow en soft))

 

- l'instruction servo.write prends entre 48 et 49µs, indépendament du nombre de servos actifs. Écrire une nouvelle valeur pour chacun des 8 servos prends donc moins de 0.4ms. Donc il faudrait que tu donnes plus de 1000 consignes à chaque moteur chaque seconde pour n'utiliser que 50% du temps de calcul.

 

- la génération des signaux pour 8 servos prends environ 0.5% du temps d'exécution : ce n'est donc à priori pas l'élement limitant.

 

Donc à priori, je dirais que la libraire servo n'est pas en cause (à voir pour le calcul de cinématique inverse)




#111930 FourBarQuad525 - Toujours plus rapide

Posté par Sandro - 04 décembre 2020 - 12:12

Bonsoir,

je confirme les dires de pat92fr :

tu lances le mouvement des 4 pattes, puis tu fais une pause pour leur laisser le temps de se rendre à la position indiquée.

 

Pour les modifications du code :

- tu enlèves le "delayMicroseconds" de InverseKinematics

- tu remplace la fonction forward par :

void Forward(){
  static unsigned long last_time = micros();
  for(int i=0;i<lgTab;i++){
    InverseKinematics(FRx[i],FRy[i],FRLS,FRRS);
    InverseKinematics(BLx[i],BLy[i],BLLS,BLRS);
    InverseKinematics(FLx[i],FLy[i],FLLS,FLRS);
    InverseKinematics(BRx[i],BRy[i],BRLS,BRRS);

    //on attends de manière à avoir une durée d'exactement Speed avant de lancer la consigne suivante
    while(micros()-last_time<=Speed)
    {
      //ne rien faire : on attend
    }
    last_time += Speed;
  }
}

(j'ai vérifié, ça compile).

 

Prends une trajectoire qui fonctionne, et fait la modif : à priori, ça devrait continuer à fonctionner sans problème

 

Bonne soirée

Sandro
 




#111917 FourBarQuad525 - Toujours plus rapide

Posté par Sandro - 02 décembre 2020 - 08:52

Bonsoir,

du coup voici ma première amélioration : on essaye de maintenir une vitesse proche de la vitesse max pour un des deux servos (adaptant l'autre en conséquence).

Avant :

global_v4.2.png

Nouveau:

global_v4.3.png

 

La forme du chapeau est quasiment inchangée:

Avant:

trajectoire_v4.2.png

Maintenant:

trajectoire_v4.3.png

 

Qu'est ce que j'ai changé?

J'ai simplement écarté un peu plus les points quand les servos allaient lentement : j'ai ainsi pu "gagner" 4 points : il y a donc maintenant 30 points au lieu de 34 : le cycle s'effectue donc maintenant 11.7% plus vite.

Reste à vérifier si les servos suivent effectivement.

 

Comment aller encore plus loin?

Sur la phase de stance, on voit que c'est d'abord un moteur qui vas vite, puis l'autre : je pense qu'on pourrait gagner 2-3 points en faisant se chevaucher les zones où les deux moteurs vont vite (nb : ça change la trajectoire)

Sur la phase de swing, on n'est pas encore à une vitesse constante égale au pic : je pense qu'on doit pouvoir encore y gagner au moins deux points (un avant et un après le sommet du chapeau)

 

 

 

En pièce jointe : les versions 4.2 ("avant" : j'ai juste modifié la mise en page) et 4.3 (avec les modifs pour j'espère gagner du temps):

Fichier(s) joint(s)




#111903 FourBarQuad525 - Toujours plus rapide

Posté par Sandro - 01 décembre 2020 - 09:36

Merci, j'ai donc prix un temps de 6.8ms par itération (@Oracid : ce serait plus propre d'utiliser micros() et d'attendre de manière active jusqu'à la fin de la durée souhaitée : comme ça, tu es sur de la période)

La vitesse la plus importante obtenue est 700°/s (en swing) et de l'ordre de 600°/s enstance

 

J'ai rajouté aussi l'accélération (courbes en bas à droite, une fois avec tous les points visibles (mais ça écrase tout), et une fois en faisant un zoom verticalement). Il y a quelques valeurs extrêmes ateignant les +- 100 000°/s², mais la quasi totalité sont en dessous de 12 000 °/s², et la grande majorité sont en dessous de 5000°/s

Il y a donc de petits pics (lors des "coins" du chapeau) qui sont probablement irréalisables, mais le moteur rattrapera un peu après

 

Voici la version mise à jour :

Fichier(s) joint(s)




#111898 FourBarQuad525 - Toujours plus rapide

Posté par Sandro - 01 décembre 2020 - 08:00

Bravo!

 

Du coup j'ai commencé à travailler sur des données pas tout à fait à jour, mais ça fait rien

Je te mets en pièce jointe une V3 de l'excel, avec en plus une grande figure à droite qui regroupe tout (position x et y, angle des servos et vitesse, le tout en fonction du numéro de point (donc indirectement du temps)

 

Voici ce que ça donne (j'ai rajouté les rectangles ensuite à les rectangles sous "paint"):

chapeau_chinois_normal___excel_v3_annoté.png

Zone 1: on voit que les deux moteurs vont assez lentement : du coup il est pprobablement possible d'augmenter leurs vitesses (en gardant la même proportion, ie on modifie la longueur des segments mais pas leur pente). Après, il faut faire attention, on est au milieu du stance, là où il y a probablement le plus de poids sur la jambe: donc il faudra faire attention de ne pas vouloir aller trop vite (les servos étant plus lents sous un grand couple)

Zone 3: on est dans le swing, donc pas beaucoup d'efforts à fournir. Si les moteurs arrivent à suivre ce pic de vitesse, alors on peut augmenter les vitesses des zones 2 et 4 (de nouveau, en allongeant les segments en gardant leur pente)

 

 

Je te suggère de mettre à jour l'excel avec tes nouveaux paramètres (longueur du fémur et trajectoire en chapeau chinois 11.1) et de poster la figure résultante : on verra alors où on peut espérer grater un peu de vitesse

Fichier(s) joint(s)




#111888 FourBarQuad525 - Toujours plus rapide

Posté par Sandro - 30 novembre 2020 - 11:27

Avec plaisir.

 

En fait, le plus dur, c'est d'avoir les formules exactes de la cinématique inverse (parfois c'est tellement compliqué qu'on abandonne et qu'on procède par approximations successives à partir de la cinématique directe : dans ce cas, on sera assez bloqué ensuite pour utiliser excel).

Une fois qu'on a des formules exactes, il suffit de les recopier dans excel (qui comporte toutes les fonctions mathématiques usuelles), avec une colonne par variable intermédiaire. Certes, ça fait beaucoup de colonnes (et les formules ne sont pas très lisibles sous excel), mais ça se fait sans trop de difficulté.

Ici, là seule petite "difficulté" était le "if(e<0) S=-S", mais excel gère aussi les "Si", donc pas de problème.

Si par contre il commence à y avoir des boucles ou de la récurrence, alors c'est à peu près mort pour utiliser excel.

 

 

Par contre, s'il te plait, avant d'envisager d'utiliser les résultats, vérifie les valeurs de S1 et S2 pour une ou deux valeurs (ie regarde si ta fonction Arduino donne le même résultat). Vu que les formules Excel sont très indigestes, il est bien possible que j'ai laissé passé une étourderie (j'en ai fait au moins une que j'ai détecté car j'essayais de calculer des acos de nombres plus petits que -1, mais peut-être qu'il en reste d'autres).

 

 

Pour l'interprétation, il faudra voir en fonction de la courbe obtenue. Mais globalement, l'idée est que si sur un segment la vitesse des deux moteurs est lente, alors ce segment peut probablement être plus long (ie on peut le parcourir à une vitesse plus élevée). Inversement, là où les vitesses sont les plus élevées, il faut se méfier, c'est un des endroits où le risque est le plus élevé que les servos n'arrivent pas à suivre la consigne.

NB : cette analyse reste forcément biaisée, vue qu'elle ne tient pas en compte le couple à fournir, mais ça donne déjà des indications.

 

Je te propose qu'on en discute plus en détail quand tu aura un premier graphe des vitesses (nb : il ne sert à rien sans les deux autres, car sinon on ne voit pas à quelle partie du cycle ça correspond).

N'hésite pas à poster le fichier excel (dans un zip, car directement ça ne marche pas) en plus des figures, comme ça on pourra le modifier directement.




#111886 FourBarQuad525 - Toujours plus rapide

Posté par Sandro - 30 novembre 2020 - 07:39

Bonsoir,

du coup, je t'ai fais un tableau excel (en pièce jointe) pour calculer la position et la vitesse approximative (différence de position divisée par le temps), en me basant sur ta fonction de cinématique inverse.

 

NB :

- j'ai pas une trajectoire complète, donc à toi de compléter le tableau vers le bas

- les figures sont sous le tableau (il y en a 3 : la trajectoire (qui correspond à ce que tu faisais déjà), la trajectoire angulaire des deux servos, et une approximation de leur vitesse)

- si tu veux une vitesse "absolue" des servos, tu devra ajuster le paramètre dt (en haut) : il s'agit de la durée entre deux points successifs (les 2ms correspondent au cas idéal où seul les delay ralentiraient le code)

- Attention, j'ai pas vérifié les calculs : donc fait un ou deux calculs avec ta fonction de cinématique inverse pour vérifier que je n'ai pas fais d'étourderies

 

Si tu as besoin d'aider ou si quelque chose n'est pas clair, n'hésites pas à demander.

 

 

PS : tu utilises mal le mot clef "static" dans ta fonction de cinématique inverse :

- static sert à ce souvenir de la valeur d'une variable d'un appel à une fonction à l'appel suivant, avec initialisation seulement la première fois. Par exemple :

void compter()
{
   static int n=0;
   n=n+1;
   Serial.println(n)
}

void loop()
{
    compter();
}

vas afficher les entiers 1,2,3, ... (au lieu de toujours 1 si tu enlèves le mot clef static)

 

Dans ton cas, tu voulais probablement utiliser "const" à la place de static (const signifie que la "variable" ne changera jamais de valeur (ce qui permet au compilateur de mieux optimiser, et de t'avertir si par mégarde tu cherches à modifier la "variable")

Fichier(s) joint(s)




#111872 FourBarQuad525 - Toujours plus rapide

Posté par Sandro - 29 novembre 2020 - 04:30

Bonjour,

bravo pour toutes tes expériences!

 

Du coup, ça m'a fait un peu réfléchir a ton problème. Voici quelques pistes auquelles j'ai pensé:

1) Est-ce que la durée entre chaque point est bien constante? Si oui, alors tu peux probablement augmenter légèrement l'écart entre les points en mode "swing". En effet, un moteur DC (comme ceux contenus dans les servos) vont d'autant plus vites qu'ils ont peu de couple à fournir : ils devraient donc pouvoir aller un peu plus vite en swing qu'en stance.

 

2) Est-ce que tu penses que tu arriverais facilement à ajouter ta cinématique inverse dans le tableau excel? Si oui, je penses que ça pourrait être intéressant d'avoir les positions angulaires et les vitesses des deux servos d'une patte. Pourquoi? Car a priori, il est difficile d'estimer la vitesse de chaque servo pour une vitesse du bout de la patte.

2.1) Ainsi, si tu as une vitesse V en bout de patte, il est possible que tu ais une vitesse de rotation Vth=0 pour un servo et Vth=Vth_max pour l'autre (dans quel cas, tu peux difficilement aller plus vite), mais il est aussi bien possible que les deux servos soient en dessous de leur vitesse max, dans quel cas il devrait être possible d'augmenter (proportionnellement) la vitesse des deux servos sur ce segment.

2.2) Si tu vois que la vitesse du servo 1 est forte avant T0 et que celle du servo 2 est faible pendant ce même temps, et qu'après T0 la tendance s'inverse, alors tu peux envisager d'avoir une période de recoupement (où les deux servos ont une vitesse relativement élevée) : ça changera un peu la trajectoire, mais si ce changement n'est pas problématique, alors tu peux gagner du temps

 

3) Si tu arrives à mesurer le courant fournit par un servo (par exemple avec une toute petite résistance entre la masse et l'alim négative du servo), alors tu peux voir l'évolution du courant au court d'un cycle : si le courant est faible à l'instant T, c'est que le servo ne force pas, et qu'on peut donc voir s'il peut aller plus vite (s'il n'est pas déjà à vitesse max)

 

4) Si tu es prêt à souder un fil directement sur le potentiomètre du servo (ou d'acheter un servo avec ce fil en plus ou un servo "intelligent"), alors tu peux vérifier si le servo atteint la position désirée dans le temps impartit : si oui, tu peux essayer d'accélérer le segment correspondant

 

 

Pour l'allure même de la trajectoire :

5) Minimiser les variations de hauteur du centre de masse du robot est probablement une bonne idée (à chaque fois qu'on monte le centre de masse, il faut fournir de l'énergie, et je penses qu'on ne récupère qu'une petite partie de cette énergie). Après, en soit, ton but ne semble pas être d'économiser la batterie mais d'aller au plus vite, donc c'est peut-être moins pertinent (mais si on peut utiliser la puissance fournie pour avancer plutôt que pour faire monter le robot, je penses qu'on y gagne quand même)

6) Même si les petits servos moteurs ont très peu d'inertie, un changement de vitesse n'est pas instantané : à priori, j'aurais donc tendance à croire que des "coins" (comme les extrémités gauche et droites et hautes de ton chapeau chinois) ne soient pas optimales. Il vaudrait eut-être mieux lisser un peu la courbe si c'est possible (mais je penses pas que ça ait un effet significatif)




#111868 Construction d'une imprimante 3D Prusa I3 en kit.

Posté par Sandro - 29 novembre 2020 - 11:03

Est-ce que sur la prussa i3 tu peux faire un home manuel directement depuis l'imprimante?

Si oui, je penses que ce serait intéressant de voir le résultat : si tout marche bien, alors le problème vient de Repetier, si le problème persiste, le problème vient de l'imprimante (hardware, firmware ou configuration)




#111716 Communication arduino vers micro-ordi en environnement bruité

Posté par Sandro - 20 novembre 2020 - 06:24

Bonsoir,

le problème c'est que c'est de longs câbles qu'il faudrait blinder. Et si on blinde des cables sur de grandes longueurs, on se retrouve avec une grosse capacité sur le bus, ce qui pose aussi des problèmes.

 

Après, je n'exclus pas une solution hardware (par exemple utilisation d'un autre protocole ou d'un convertisseur). J'ai d'ailleurs commandé deux circuits "d'extension I2C" pour tester, mais il y a j'espère mieux comme solution




#111688 Horloge avec des LEDs adressables

Posté par Sandro - 14 novembre 2020 - 04:58

Bonjour,

fais attention à deux points avec ton convertisseur de tension :

- le LM323T n'est plus disponible chez RS (mais peut-être ailleurs)

- le courant de 3A annoncé est sous réserve de non sur-chauffe. Si tu ne mets pas de dissipateur thermique, tu aura beaucoup moins de courant que ça. La température max de la jonction est TJ_max=125°C, la résistance thermique vers l'air ambiant est Rth_JA=50 °C/W. Si on suppose une température de l'air de TA=25°C, on a donc une puissance max dissipable par le composant de P_max=(TJ_max-TA)/Rth_JA = (125-25)/50=2W

Comme le LM323T est un régulateur linéaire, le courant de sortie est quasiment identique au courant d'entrée, mais la tension est moindre. La différence est dissipée en chaleur.

P_dissipé=I*(Vin-Vout) soit Imax=P_dissipé_max/(Vin-Vout)

Si on prends P_dissipé_max=P_max, alors on a Imax=2/(9-5)=2/4=0.5A

 

Sans dissipateur, tu pourra au maximum utiliser 0.5A au lieu des 3 annoncés (en supposant que tu alimentes ton montage depuis une pile 9V, si tu l'alimentes en 12V, c'est encore pire)

Donc soit il te faut un dissipateur thermique, soit tu peux prendre un convertisseur basé sur du hachage, comme celui-ci : https://www.robot-ma...12v-3a-210.html