Aller au contenu


Photo

Robot Quadrupède intelligent.

robot quadrupède

  • Veuillez vous connecter pour répondre
178 réponses à ce sujet

#21 ashira

ashira

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 290 messages
  • Gender:Male

Posté 11 juillet 2015 - 10:56

Ca marche ! N'hésite pas si tu as des questions !

#22 ashira

ashira

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 290 messages
  • Gender:Male

Posté 13 juillet 2015 - 01:32

Comme chaque week end, j'essai d'avancer peu à peu et de vous donner des nouvelles. Deux autres pièces de faites: Les côtés de la tête.

Photo: WP_20150713_001.jpg

#23 ashira

ashira

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 290 messages
  • Gender:Male

Posté 23 août 2015 - 12:24

Le pan/tilt de la tête est imprimé et fonctionne!

J'utilise maintenant une arduino due pour essayer d'augmenter la vitesse des échanges entre le pc et la carte. Ca marche plutôt bien, je transmets les coordonnées x et y des objets détectés, le nombre d'objet et visage détectés, les fps de la caméra et l'heure, sans aucun ralentissement visible ! Je vous mets une petite vidéo :

https://www.youtube....h?v=XomSzZmuVVg :)



#24 Sparda

Sparda

    Nouveau membre

  • Membres
  • 26 messages
  • Gender:Male

Posté 24 août 2015 - 07:55

Waah content de voir que ton projet avance!
Bientôt si tu lances l'objet il court pour aller le chercher, non ? ^^
La vitesse d’exécution n'est pas plus rapide si tu fais tout traiter par le pc embarqué ?



#25 ashira

ashira

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 290 messages
  • Gender:Male

Posté 24 août 2015 - 04:51

On y est pas encore! Mais qui sait un jour ^^ sinon, bonne question. En fait faut prendre en compte le robot au complet: Si je traite tout par le pc, il faut retourner toutes les infos des capteurs au pc, et qu'il renvoie les infos pour les moteurs. Alors que la, l'arduino récupère seulement les infos nécessaires du pc, et envoie les infos à une autre carte qui s'occupe des moteurs. Il y a moins d'échange avec cette méthode. Ce qui limite surtout les échanges c'est le delay (actuellement à 1ms) qui est obligatoire à chaque fois que je récupère un caractère du pc. Je vais faire des testes en diminuant cette valeur pour voir si ca fonctionne! Mis à part celui ci, j'ai banni le delay de mon programme :)

#26 Loewyn

Loewyn

    Nouveau membre

  • Membres
  • 13 messages

Posté 24 août 2015 - 06:16

Impressionnant ! Bonne chance pour la suite



#27 Loewyn

Loewyn

    Nouveau membre

  • Membres
  • 13 messages

Posté 24 août 2015 - 06:16

Impressionnant ! Bonne chance pour la suite



#28 Sparda

Sparda

    Nouveau membre

  • Membres
  • 26 messages
  • Gender:Male

Posté 25 août 2015 - 11:08

On y est pas encore! Mais qui sait un jour ^^ sinon, bonne question. En fait faut prendre en compte le robot au complet: Si je traite tout par le pc, il faut retourner toutes les infos des capteurs au pc, et qu'il renvoie les infos pour les moteurs. Alors que la, l'arduino récupère seulement les infos nécessaires du pc, et envoie les infos à une autre carte qui s'occupe des moteurs. Il y a moins d'échange avec cette méthode. Ce qui limite surtout les échanges c'est le delay (actuellement à 1ms) qui est obligatoire à chaque fois que je récupère un caractère du pc. Je vais faire des testes en diminuant cette valeur pour voir si ca fonctionne! Mis à part celui ci, j'ai banni le delay de mon programme :)

 
Si je pige bien, le pc ne fait que du travail de haut niveau, (donne la direction à suivre, accélère, stop...) et le travail de bas niveau est fait par l'arduino et la carte moteur (récupérer les angles/positions de chaque moteurs).
Je suppose que ton delay de 1ms est dû à la récupération des ordres venant du pc par l'arduino avec un if (Serial.available() >0) ?
Normalement la communication est de 9600 bauds (soit 9600 caractères par seconde) donc tu peux descendre à 0.1ms en spammant l'instruction dans la void loop. Et tu peux aller encore plus loin (si ton transmetteur/recepteur le permet) en augmentant le baud rate lors du Serial.begin()



#29 ashira

ashira

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 290 messages
  • Gender:Male

Posté 26 août 2015 - 03:28

Le pc fait même moins que ça, il envoie juste ce que la caméra voit sous forme de variables. Toutes les "décisions" sont dans l'arduino.

C'est exactement ca pour le delay. Que veux tu dire par "en spammant l'instruction dans la void loop."?
Actuellement la transmission se fait à 115200bauds. Le délai m'embête d'autant plus que j'ai 27 caractères à lire (et bientôt beaucoup plus) avant de commencer à faire une loop, donc 27x le délai. Je vais faire des testes, je posterai le résultat ;)

#30 Sparda

Sparda

    Nouveau membre

  • Membres
  • 26 messages
  • Gender:Male

Posté 26 août 2015 - 06:54

Ah oui en effet il fait pas grand chose, tu pourrais "presque" l'enlever ^^'

Mais avec le Serial.availabe() tu n'es pas obligé de fixé un delay derrière, tu peux lire aussi vite que le fonctionnement de la void loop en supprimant ce delay de 1ms  (c'est ça que j'appelle en spammant l'instruction dans le void loop).
Si tu as 27 caractères à lire tu peux utiliser Serial.readStringUntil() (en rajoutant un 28ème caractère de fin de chaîne) et l'écrire dans une variable string qui peut être lu comme un tableau dont la dernière case se termine par un null.



#31 ashira

ashira

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 290 messages
  • Gender:Male

Posté 26 août 2015 - 08:12

Bha justement je viens de faire des testes, ca va jusque 100 microsecondes, en dessous ca bug( la tête bouge un peu de temps en temps) et en dessous de 40 plus rien ne se passe. J'utilise peut être mal le code..

Je n'ai jamais utilisé cette fonction, c'est quoi son avantage par rapport au Serial.availabe()?

#32 Sparda

Sparda

    Nouveau membre

  • Membres
  • 26 messages
  • Gender:Male

Posté 27 août 2015 - 12:33

Cool, tu gagnes déjà un facteur 10 =)
Si tu veux je peux jeter un œil à ton code en MP

Je t'ai mis en hyperlien (dans mon précédant post) l'aide arduino de ces fonctions (après c'est en anglais ^^')
Le Serial.readStringUntil() ne remplace pas le Serial.available() (qui lui sert juste à savoir si tu as des données disponible (>0) et la quantité de données (nombre renvoyé).
Le readStringUntil() peut remplacer le Serial.read() (qui lit et renvoie le premier bit de données disponibles), par une lecture de l'ensemble des données jusqu'à soit un bit (char) de fin que tu renseignes comme argument de fonction. (ou pendant un temps déterminer (avec une seconde instruction Serial.setTimeOut() mais pas utile pour ton projet).
(J'espère que je suis clair)

Pour l'instant, je n'ai pas personnellement implémenter la readStringUntil() dans mon code car je ne lis que trois données toutes les 5ms. La semaine prochaine, je vais tâcher de faire des essais avec celle-ci, et je te ferais un petit retour.



#33 ashira

ashira

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 290 messages
  • Gender:Male

Posté 27 août 2015 - 05:25

Ca marche je t'envoie ça. ;) Mais si je peux réellement supprimer mon delay avec le Serial.availabe(), je n'ai pas vraiment d'avantage à utiliser autre chose. (?)



#34 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 8 015 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 27 août 2015 - 09:41

Ce qui limite surtout les échanges c'est le delay (actuellement à 1ms) qui est obligatoire à chaque fois que je récupère un caractère du pc. Je vais faire des testes en diminuant cette valeur pour voir si ca fonctionne! Mis à part celui ci, j'ai banni le delay de mon programme :)

 

Hum ... Pourquoi " Obligatoire " ? 

En tout cas en effet il faut complètement bannir le delay de ton programme... 
Si vraiment d'un délay d'attente utilise la fonction millis()  ;)  

 

 genre : 

int delay = 0;    // temps d'attente voulu en ms -1
long temps0=millis(); 
while ( millis()< (temps0+ delay))   // si delay =0 le temps d'attente sera de  1 ms à cause du <
{
}

Ensuite je te propose de mettre ton code  ( au moins la partie transmission des données ) ici ... 

Personnellement je ne vois pas du tout où est ton problème ... 

Sais tu que tu peux faire :  

if (Serial.available>Nbyte)
{
 char byte[Nbyte];
 for (uint8_t i =0; i<Nbyte; i++)
 {
 byte[ i]= Serial.read();
 }
}

attention à avoir Nbyte < 64

 

Ensuite en effet si tu une trame complexe avec des caractère spéciaux,

La fonction readStringUntil(); est particulièrement utile. 

 

Surtout si c'est toi qui envoit les données via ton moniteur sérial ;) 
Essaye d'envoyé la valeur '123' à ton arduino et tout ce qu'elle va voir c'est les caractères séparés ;) 

 

Bref poste ton code je suis sûr que ça peut se régler rapidement. 

Je commande des robots et fais des retour sur le port série avec parfois bien plus de 27 bytes et j'ai pas ces problèmes là ;) 

Par contre conseil : Met en place à minima un check sum ;)  et un byte de start ;) 

Après si tu as des trames de longueurs variables choisis aussi un byte de stop et un byte "caractère spéciaux" =) 
 

 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !

 

Les réalisations de Mike118  

 

 

 


#35 ashira

ashira

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 290 messages
  • Gender:Male

Posté 27 août 2015 - 10:27

"Obligatoire" parce que si je l'enlevé ça ne fonctionne plus.

 

Mais j'ai peut être une piste, j'ai un gros doute sur la manière dont j'utilise strtok_r. Le "NULL" ne doit pas apparaître qu'en dernier ? 

 

Voici le code pour la transmission :

#include <string.h>   
#include <Servo.h>
Servo myservox;    
Servo myservoy;

char data[19]={           //roborealm me renvoie 19 caractères au maximum
   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

int incrx;                      
 int incry;
char *distancex;
 char *distancey;
 char *nbrf;//nbr de face
 char *nbro;//nbr d'objet
 char *FPS;
 char *i;
 int x;
 int y;
 int nof;
 int noo;
 int fps;
int anglex = 90;
 int angley = 90;
 int k=0;
long timer;// horloge realm long
char *htc;//horloge
long timerp;// valeur étape suivante timer
int delaiT;// delai du prochain pan/tilt recherche
int basculedelaiT;
int rx;//random angle x
int ry;// random angle y
void setup()//je mets en position initiale le pan/tilt.
 {
   Serial.begin(115200);
basculedelaiT=1;
  myservox.attach(30);
   myservox.write(anglex);
   delay(500);
   myservoy.attach(31);
   myservoy.write(angley);
   pinMode(13,OUTPUT);
}


void loop()
 {

  if(Serial.available()){     
     while (k<19){                  
       data[k] = Serial.read();
       k++;                            
       delayMicroseconds(100);                   
    }
 
////////
    distancex = strtok_r(data,";",&i);      
     distancey = strtok_r(NULL,";",&i);      
     nbrf = strtok_r(NULL,";",&i);
     nbro = strtok_r(NULL,";",&i);
     FPS = strtok_r(NULL,";",&i);
     htc = strtok_r(NULL,";",&i);
///////
    
     x = atoi(distancex);                           
     y = atoi(distancey);
     nof = atoi(nbrf);
     noo = atoi(nbro);
     fps = atoi(FPS);
     timer = atol(htc);
     k=0;

le code n'est pas indenté..

 

 

-En utilisant la fonction millis() comme tu me l'as présenté, en gros ca va automatiquement prendre la plus petite valeur fonctionnelle ?

 

-De même pour ton code avec "if (Serial.available>Nbyte)", le nombre de caractère transmis s'ajuste c'est ça?   

 

En effet j'ai un caractère spécial, je sépare les variables par " ; "

voici le setup de la com : com.jpg

 

Qu'est ce qu'un check sum ? Et comment faire un bytes pour caractères spéciaux ? ( et pourquoi aussi ?^^)

 

Merci pour votre aide ! ;)



#36 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 8 015 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 27 août 2015 - 10:43

Déjà premier point : 

essaye 

if ( Serial.available>19)
{ 
 for (uint8_t i =0; i<19; i++)
 {
  data[i]= Serial.read();
   }
}

normalement ton problème sera réglé ;) 

En gros ton programme attendra d'avoir reçu tes 19 bytes dans le buffer ... Comme ça plus d'erreur possible de raté données ou autre ;)

 

 

Ensuite en simplifié :  la fonction millis() te permet de connaitre le temps en milliseconde qui s'est écoulé depuis que ton système est allumé. Cela ne bloque pas ton programme comme un delay le fait et n'a pas de problème hazardeux quand tu as des interruption. 
Et le gros avantage c'est que je sais pas toi mais  personnellement quand j'ai besoin d'attendre un certains temps pour faire une tache, pendant ce temps là j'aime bien faire autre chose et un la fonction millis() bien utilisé peut te le permettre ;)

 

exemple : 

void loop()
{
 if (millis()> (temps0+delay))
 {
   counter1++;
   temps0=millis();
 }
 counter0++; 
}

Dans ce cas précis : counter0 va s'incrémenter plein de fois en attendant que suffisamment de temps passe pour que le cas  "millis()> (temps0+delay) "  soit vérifié...
 

 

 

 Le checksum , il sagit d'un byte qui est égale à la somme de tous les autres qu'on met généralement à la fin pour des simplification de codage et il est utilisé pour vérifier l'intégrité de ta trame. ( Le byte check sum sera automatiquement modulo 256 puisque par définition il tient sur 8 bits ... ) 

 

En fait, si tu envois plein de byte à la suite, due à des perturbations ou autre, il se peut que tu ais des données qui soient mal reçu. au lieu de recevoir  10001100  sur un des 19 bytes tu peux par exemple recevoir 11001100 ... ce qui peut éventuellement être problématique ... Comportement bizarre du robot erreur de comportement etc ...  Pour gérer ça tu peux trier tes info intègres des info qui sont fausse en comparant le checksum avec la sum de tous les autres caractères reçu ... 

Typiquement sur du filaire tu peux avoir du 2% de pertes ... et voir du 5% si tu passe par bluetooth ou autre ... 

 

 

Ensuite, à partir du moment où tu as un trame un peu complexe, dont la longueur peut varier ou autre, tu peux décider de mettre des caractères spéciaux : 
Un caractère de début de trame pour indiquer quand commence ta super trame;

Un caractère de fin de trame pour indiquer quand elle fini. 

 

Hors ces deux caractères que tu peux choisir comme tu veux entre 0 et 255 ( 8 bits oblige) sont des caractères spéciaux; ça veut dire que soit tu n'as plus le droit de les utiliser dans le reste de ta trame soit il te faut une astuce : le caractère de caractère spéciaux ! 

Supposons que le start soit : 0x01   que le stop soit  0xFE   et que le caractère spécial soit 0x55; 

 

supposons que tu veux envoyer les données 0x02 et 0x03 

 

ta trame d'envoit sera : 0x01 0x02 0x03  CHECKSUM 0xFE 

 

avec dans ce cas CHECKSUM = 0x02+0x03   ( certains ajoute aussi le byte de start ... ) 

Si maintenant tu veux envoyer  les données : 0x02  0xFE 

 

Ta trame sera :  0x01 0x02 0x55 0xFE  CHECKSUM 0xFE 
 le byte caratère spécial est ajouté pour indiqué que le caractère qui suit est un caractère normal qui a la valeur d'un caractère spéciale ! Il est à utilisé si tu souhaite envoyer en donnée ton stop ton start mais aussi ton indicateur de caractère spécial !  

Exemple de trame plus complexe : 

Je veux envoyer :  0x02  0x03 0xFE 0x05 0x55 0x01

Ma trame sera : 0x01 0x02  0x03 0x55 0xFE 0x05 0x55 0x55 0x55 0x01 CHECKSUM 0xFE. 

Après il existe d'autre façon de coder des trames, le checksum n'est pas obligatoires non plus ... 
Bon je te laisse écrire tes fonction d'écriture et de lecture de trame ;) C'est formateur ! 
 

Enjoy !

 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !

 

Les réalisations de Mike118  

 

 

 


#37 ashira

ashira

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 290 messages
  • Gender:Male

Posté 27 août 2015 - 11:26

C'est bien utile cette fonction! J'imagine bien utiliser cette technique pour contrôler la vitesse de servomoteurs en faisant des pauses variables entre chaque incrémentations, sans bloquer et ralentir la loop!

Pour la solution, il reçoit bien quelque chose mais il a seulement des spasmes quand il voit mon visage. (j'ai faillit être vexé :) )
J'ai testé avec et sans Delay, même résultat. Donc ca a l'air de supprimer le délai"obligatoire". J'ai aussi essayé a 9600 bauds, même résultat. Ca ne viendrait pas des NULL repetitifs?

Je vais potasser cette histoire de trame! En gros ca permettrait de recevoir un data avec un nombre de variable différents, sans toucher au nombre de caractère que je reçois à chaque fois dans le programme? Un coup 19 caractères, un coup 16, 9 etc..

Je nage un peu ^^

#38 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 8 015 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 27 août 2015 - 11:39

Hum, 

Sans savoir quels sont les données envoyées, difficile de définir l'origine de ces spasmes... 

Il y a plusieurs points à vérifié : l'intégrité des données envoyées ( si elles sont bien envoyées),  l'intégrité des données reçue ( et si elles sont bien reçues) , l'intégrité du traitement des données reçues ( si elles sont traitées ) . , intégrité des actionneurs, intégrité des alimentation ....

Typiquement si ton pc envoit un flot de données " Null" au milieu des données " à utilisé " et que tu ne traites pas ces données ... ça pourrait expliquer les spasmes ( vérification de l'intégrité des données envoyées ) 
Idem si en fait tu as toi en environnement très perturbé avec 50% d'échec en envoyant tes données à avec ta vitesse d'envoit ( Intégrité des données reçue ) Essaye eventuellement de repasser à 9600 bauds 
Enfin si ton robot traite pas bien les données ... là aussi spasmes possible ... 

etc... 



 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !

 

Les réalisations de Mike118  

 

 

 


#39 ashira

ashira

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 290 messages
  • Gender:Male

Posté 28 août 2015 - 03:48

J'ai continué les testes selon tes suggestions. Pour les testes, la dernière variable du data envoyé sont les fps de ma caméra. J'ai écris que si ca chutait en dessous de 20fps, la led au pin 13 s'allume. Si c'est au dessus de 20fps elle s'éteint. Et ca réagis comme il faut, a 115200 bauds et a 9600 bauds.
Et il y a toujours une valeur envoyée entre deux ";". Par exemple, s'il ne voit pas d'objet, il n'envoie pas rien, il envoit "0".

Je continuerai les testes sûrement demain, mais si tu as des piste n'hésite pas !

#40 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 8 015 messages
  • Gender:Male
  • Location:Anglet
  • Interests:Robotique, Entrepreneuriat, Innovation, Programmation, Résolution de problème, Recherche de solutions, Mécanique, Electronique, Créer, Concevoir

Posté 28 août 2015 - 11:52

Hum visiblement les rapides conclusions des tes petits tests sont : 


Je sais que j'envois une donnée : Mon nombre de fps  ( donnée sans doute affichée sur ton écran en " temps réel" ) il varie entre x<20 et y >20 . 
J'ai écris un " script " qui est censé être capable d'extraire la valeur d'une trame dont fait partie le nombre de fps. 

J'ai fais une fonction qui interprète la donnée extraite de la trame et effectue une action en conséquence. 

 

J'observe que l'action effectuée est en accord avec la donnée que j'envoie 

Donc : tu envois bien le bon nombre de fps, ton script capable d'extraire la valeur d'une trame semble être efficace ( sauf si malheureusement ça fonctionne que pour cette donnée ) , et ta fonction fonctionne correctement. Ok. 

Maintenant vérifie ces même " blocs" pour ta détection : vérifie que si tu envoies bien toi manuellement un trame ( via la console par exemple ) tu arrive bien à l'extraire, genre en l'affichant sur la console aussi ... Et vérifie que si ta fonction qui est censé faire bouger la tête bouge bien comme elle est censée bouger quand tu envois ces info ... 

 

Si c'est deux choses fonctionnes c'est que peut être tu ne reçoit pas ce que tu pense devoir recevoir, exemple : possible que tu regardes pas le bon byte ou autre ?

 

Bref si tu as un écrans LCD ça peut être utile aussi pour du débug: tu peux afficher dessus ce que tu reçoit  etc...

 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !

 

Les réalisations de Mike118  

 

 

 






0 utilisateur(s) li(sen)t ce sujet

0 members, 0 guests, 0 anonymous users