
Glenn Robot Humanoide
#941
Posté 02 août 2019 - 07:00
Mais à ta place, je ne ferais pas ça.
Ma chaine YouTube : https://www.youtube..../oracid1/videos
#942
Posté 02 août 2019 - 07:10
Le but est tout de même d'avoir une carte électronique fait maison à placer dans Glenn, qui me permettra donc de basculer en brancher sois une alimentation sur secteur dessus, sois utiliser des batteries interne au robot.
Et ouais je vais éviter se genre d'alimentation ^^ trop peur de faire une connerie.
#943
Posté 02 août 2019 - 08:25
Peut-être qu'en s'en inspirant tu pourrais y arriver.
Il y a peut-être une piste à suivre, c'est les tablettes faites à partir de Raspberry Pi.
Ma chaine YouTube : https://www.youtube..../oracid1/videos
#945
Posté 28 août 2019 - 09:43
Bon, un p'tit retour, je supprime le capteur de température, après trois essais avec trois capteurs différents et donc trois façons de les brancher ça merdouille tout le temps, donc je ne vais pas me prendre la tête hop plus de ventilos.
Ensuite, le capteur de distance VL53l envoi bien les valeurs de l'esp à la pi, mais au bout de quelques minutes j'obtiens un temps de latence de plusieurs minutes avant d'avoir la bonne valeur à la PI, donc pas top non plus, là je me pose la question de savoir si c'est d'avoir 3 choses branchés en I2C (capteur de distance, IMU et écran) cela m'étonne.
Si le VL53 a des latences, il et fort possible que l'IMU aussi, donc c'est vraiment pas terrible.
En revanche l'affichage sur l'écran OLED se passe très bien, pas de latence.
Je vais donc brancher l'IMU en SPI et le reste en I2C, mais si le problème vient de là je ne trouve pas ça terrible.
J'avoue que je suis un peu démotiver (c'est pas la première fois ), je vais tout de même modéliser des jambes et une partie du torse pour y placer l'électronique que j'essaye de m'amuser un peu, et si ça devient saoulant, hop je stop Glenn et je passerai peut être sur un robot à roulette, je verrai bien, mais ça me plaisait tellement de faire un p'tit humanoïde ...
#946
Posté 28 août 2019 - 01:30
Peut-être que les problèmes de capteurs ou autre affichage, ce n'est pas ce qui te passionne le plus dans ce projet.J'avoue que je suis un peu démotiver (c'est pas la première fois
)
Pourquoi ne pas te recentrer sur le problème fondamental de la bipédie, la marche ?
Ce serait vraiment dommage d'abandonner.
Courage.
Ma chaine YouTube : https://www.youtube..../oracid1/videos
#947
Posté 28 août 2019 - 01:50
Si si, j'aime beaucoup tout ça, le truc c'est que je ne comprend pas trop, de toutes façons l'erreur vient de moi pas du matériel, j'en fais surement une mauvaise utilisation ou alors j'ai un problème dans la programmation, mais je ne vois pas ou et comme pour moi toutes les erreurs sont nouvelles (apprentissage oblige) je n'arrive donc pas à rebondir correctement lol
Si je fais un résumer :
- la Pi et l'ESP communique avec la lib RS232 en RX/TX
- le capteur de distance, l'IMU et l'écran (puisque j'ai viré la sonde de température) sont en I2C
- l'ESP envoi les infos du capteur de distance et de l'IMU à la PI, ça fonctionne bien pendant un moment, ensuite le capteur de distance met du temps à envoyer l'information, j'en déduis que l'IMU doit faire pareil mais ce n'est pas flagrant.
Le seul truc qui me titille serait dans l'interruption machine, car tous les capteurs séparément fonctionne parfaitement bien en étant exécuter seul sur l'ESP.
Bon après je n'ai pas trop d'expérience.
Allez je test tout de même l'IMU en SPI, sait on jamais.Mais d'abord je fais un test sans les quelques Serial.print qui traine sur l'envoi des infos.
Edit : bon ça n'a rien changé en virant les serial.print, au bout d'un certains moment j'ai à peu prés quelques secondes de latence.
Edit : pareil en SPI.
#948
Posté 28 août 2019 - 02:11
Tu utilise quoi comme débit (baud rate) pour ra communication entre l'ESP et la Pi?
Si tu utilise le classique 9600 comme dans les exemples arduinos, tu ne peut transmettre "que" environ 1ko de données par secondes . Je ne sais pas à quelle fréquence tu les les données de tes capteurs, mais il y a de bonnes chances que tu sature la communication.
Si tel est le cas, je te conseille d'augmenter drastiquement le baudrate (il me semble que sur un arduino on peut dépasser le million de bits par seconde (baud rate = 1 000 000).
Une bonne pratique est de regarder combien d'octets tu envois par seconde (si tu envois sous forme de texte, c'est un octet par caractère + un par fin de ligne + un par fin de chaîne de caractère). Ensuite tu multiplies par 8 pour avoir le nombre de bits. Pour finir, tu multiplie par 2 tenir compte des bits qui sont "perdus" dans le protocole de communication et pour avoir un petit peu de marge. Ça te donne le baudrate minimum qu'il te faut.
Et sans avoir ton code sous la main, j'ai l'impression que tu envois des données depuis une interuption : je te conseillerais plutôt de les mettre dans un buffer et des les envoyer depuis la boucle principale
Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...
Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.
#949
Posté 28 août 2019 - 02:59
Je suis à 115200, je pense que c'est assez rapide, non ?
40 octets circules.
Sur les conseils de Mike je réunis mes données dans une structure qui passent par une Union et donc l'union sert de buffer (si je dis pas de bêtise) et c'est envoyé.
Donc actuellement je dis que dans l'interruption machine toutes les 100ms, l'esp envoi les infos à la pi, dans ma fonction je lis l'imu et le capteur de distance.
100ms car ça fonctionne bien comme ça d'après le doc de la lib RS232.
La fonction appelée dans l'interruption machine :
void espSend () { IMU.readSensor(); //lecture de l'IMU u_pi.s_pi.ms_accelX_mss = IMU.getAccelX_mss(); //les infos de l'IMU u_pi.s_pi.ms_accelY_mss = IMU.getAccelY_mss(); u_pi.s_pi.ms_accelZ_mss = IMU.getAccelZ_mss(); u_pi.s_pi.ms_gyroX_rads = IMU.getGyroX_rads(); u_pi.s_pi.ms_gyroY_rads = IMU.getGyroY_rads(); u_pi.s_pi.ms_gyroZ_rads = IMU.getGyroZ_rads(); u_pi.s_pi.ms_getMagX_uT = IMU.getMagX_uT(); u_pi.s_pi.ms_getMagY_uT = IMU.getMagY_uT(); u_pi.s_pi.ms_getMagZ_uT = IMU.getMagZ_uT(); u_pi.s_pi.ms_vl53l0x = capteur0.readVl53l0x(); //lecture du capteur de distance Serial1.write (u_pi.cast_pi, sizeof u_buf.cast_pi); }
#950
Posté 28 août 2019 - 03:24
Si tu n'as pas de Serial.write ou de Print ailleurs, alors tu es larges : tu envois 400 octets par seconde, donc 3200 bits d'information, donc si tu as un baudrate de plus de 6400, tu devrais être bon : autrement dit, tu as beaucoup de marge.
Le fait que tu fasse le write dans l'intéruption n'est pas top (on évite de faire des choses qui "prennent du temps" dans les intéruptions), mais sauf si tu utilises d'autres intéruptions, ça ne devrait pas poser de problèmes.
Du coté raspberry pi, est-ce que ton code fait en sorte que tu lise les données dès qu'elles arrivent?
Est-ce que la lecture de tes capteurs pourrait être limitante? (pour tester, envoie juste des données constantes et regarde si en 1 minute tu récupère le bon nombre de données)
Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...
Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.
#951
Posté 28 août 2019 - 03:38
Est-ce que la lecture de tes capteurs pourrait être limitante? (pour tester, envoie juste des données constantes et regarde si en 1 minute tu récupère le bon nombre de données)
Pour ce genre de test plutôt que d'envoyer des données constantes j'enverrais des timeStamp ... et je vérifierais qu'il y a pas de décalage temporel.
Si mon commentaire vous a plus laissez nous un avis !
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 !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être !
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!
#952
Posté 28 août 2019 - 03:41
@Sandro : Hummm, je crois comprendre le problème du write dans l'interruption, si l'info à envoyer dépasse le temps ou on l'interroge il pourrait y avoir conflit, c'est ça ?
Peut être que la lecture s'effectue mal du à ça au bout d'un moment, et donc latence...enfin j'imagine le truc ^^ lol
En gros, il faudrait peut être que j'essaye de cette façon, je lis les capteurs toutes les 100ms d'un coté, c'est envoyé dans la struct->union et en parallèle toutes les 100ms dans une autre fonction je fais le write ?
Ceci dis c'est peut être une autre façon de décaler le problème lol
Oui du coté Pi ça fonctionne bien, du moins c'est lu des que ça arrive, j'ai fais le test déjà avec des données constantes en laissant tourner pendant 20 à 30 mn voir plus et aucun soucis.
@Mike : je ne sais même pas ce que c'est le timeStamp ^^
(mais je vais tout de même voir sur glouglou)
#953
Posté 28 août 2019 - 07:40
Pour l'interruption, si tu as une nouvelle interruption pendant la première (la même ou une autre), ça peut commencer à faire du bordel selon le code. Du coup, on général, c'est une bonne pratique de faire des interruptions aussi courtes que possible, en particulier en déplaçant tout ce qui est communication en dehors (comparé à l'exécution du programme, ça peut être assez long). Après, je ne pense pas que ce soit le problème chez toi.
Une méthode possible est la suivante
volatile bool nouvelle_mesure; volatile ma_struct struct; dans l'interruption : ma_struct.x=lire_capteur; nouvelle_mesure=true; dans le main : if(nouvelle_mesure) { Serial.write(...); nouvelle_mesure=false; }
A noter que cette méthode a plusieurs avantages et inconvénients :
+ tu garantis que même si tu n'arrives pas à suivre, tu n’enverra jamais de vielles données
+ ton interruption ne doit plus s'occuper de la communication serie
- si le reste du main est long, tu risque de ne pas envoyer certaines données
- il y a un petit risque d'envoyer un mélange entre 2 valeurs successives si l'interruption a lieu pendant l'envoi (peut être détecté par une checksum)
- tu risque de sauter des données si tu n'arrives pas a les lire assez vite.
A noter que je ne suis pas sur si dans ton cas particulier, où tu fais le traitement des données sur l'ordinateur, cette technique soit vraiment un avantage. Quand en revanche tu veux faire du traitement sur l'arduino, ça te permet d'utiliser toujours la dernière valeur lue et de ne pas perdre de temps à traiter des valeurs obsolètes.
Pour le timeStamp, ça désigne une temps depuis un moment donné (un classique est le nombre de secondes depuis le 1er janvier 1970 (timestamp unix), mais dans ton cas, je te conseillerais plutôt le temps depuis le démarage de l'arduino (fonction millis() ou mieux micros() )
Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...
Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.
#954
Posté 29 août 2019 - 08:25
Hum, je vais éviter de m'embrouiller, mais je retiens tout de même tes suggestions
Pour ce qui est de l'interruption machine je n'ai pas grand chose :
timer.setInterval(100, timerCapteurs); /*-Tous les 100ms on envoie les données des capteurs à la PI */ timer.setInterval(100, timerLed); /*-Tous les 100ms on fait appel aux led's */ //timer.setInterval(2000,timerFan); /*-Tous les 2000ms on fait appel au capteur de température DHT22 */ (il a été supprimé du à des erreurs NAN) timer.setInterval(200, timerEcran); /*-Tous les 200ms on affiche les informations nécessaires sur l'écran */
Je vais continuer à chercher....
Edit : je viens de faire le test en laissant seulement le "timerCapteurs" et bien j'ai le même problème, au bout de quelques minutes j'ai une latence de plusieurs secondes, hum hum vite de l'essence lol
#955
Posté 29 août 2019 - 09:43
Est-ce que tu penses que tu arriverais à nous donner un code minimal? C'est-à-dire que tu enlève progressivement tout ce que tu peux du code, en gardant juste ce qu'il faut pour que le bug reste présent.
Il est bien possible qu'on faisant ça tu tombe déjà sur le bug, et dans le cas contraire on aura au moins un code simple qui reproduit ton bug, du coup ça augmente les chances qu'on arrive à comprendre d'où vient le problème.
- Mike118 aime ceci
Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...
Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.
#957
Posté 29 août 2019 - 10:56
Déjà tu peux commenter tout ce qui concerne les LED et l'écran.
Ensuite, tu continue à essayer de commenter des bouts de code et tu teste si le bug a encore lieu ou pas.
C'est vrai que ça prends un peu de temps comme méthode, mais en général ça permet de cerner assez précisément le problème.
Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...
Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.
#958
Posté 29 août 2019 - 11:00
Donc j'essaye de faire au plus court pour ne pas que cela vous brûles les yeux lol
Et en espérant ne pas avoir effacé trop de chose lol, par contre dans les fichier de la PI j'ai laissé les COUT c'est à partir de là que je vois que j'ai un temps de latence qui augmente ...
PS : je dis Arduino mais je suis sur un ESP32.
Arduino :
Com (main) :
#include "comEsp.h" //-comA gére la communication entre la Pi et Arduino #include "WS2812.h" //-Gestion des led's #include "CD_VL53L0x.h" //-Capteur de distance //#include "fan.h" //-Gestion des ventilos et du capteur de température DHT22 #include "ecran.h" //-Affichage écran #include <SimpleTimer.h> //-Timer CD_VL53L0X capteur0; //-Création d'objet pour la gestion du capteur de distance VL53L0x SimpleTimer timer; //-Création du timer void setup() { Serial.begin (115200); Serial1.begin(115200, SERIAL_8N1, 34, 32); //Rx/Tx - GPIO34 RX - GPIO33 TX permet de communiquer avec la PI timer.setInterval(100, timerCapteurs); /*-Tous les 100ms on envoie les données des capteurs à la PI */ //timer.setInterval(100, timerLed); /*-Tous les 100ms on fait appel aux led's */ //timer.setInterval(2000,timerFan); /*-Tous les 2000ms on fait appel au capteur de température DHT22 */ //timer.setInterval(200, timerEcran); /*-Tous les 200ms on affiche les informations nécessaires sur l'écran */ } void loop() { unsigned long time_start_ms; time_start_ms = millis(); Serial.print ("time_start_ms : "); Serial.println (time_start_ms); timer.run(); } void timerLed() { torsePulse(); } void timerCapteurs() { espSend(); } void timerEcran() { ecranGui01(); }
Arduino
ComESP.cpp : permet de communiquer avec la PI, je ne met pas le .h pas sur que cela soit nécessaire ?
#include <Arduino.h> #include "comEsp.h" #include "CD_VL53L0x.h" #include "MPU9250.h" #include "ecran.h" union U_DATA u_pi; union U_DATA u_buf; //extern MPU9250 IMU(Wire,0x68); extern MPU9250 IMU(SPI,15); int status; void IMU9250Setup() { while(!Serial) {} // start communication with IMU status = IMU.begin(); if (status < 0) { ecranCheck(0, 22, 14); while(1) {} } ecranCheck(1, 22, 14); } //-----On envoie les données des capteurs à la Pi //-----Serial1 correspond au Convertisseur logique void espSend () //(unsigned int readVl5310x){ { IMU.readSensor(); //On lit l'IMU u_pi.s_pi.ms_accelX_mss = IMU.getAccelX_mss(); //on stock les données u_pi.s_pi.ms_accelY_mss = IMU.getAccelY_mss(); //.. u_pi.s_pi.ms_accelZ_mss = IMU.getAccelZ_mss(); u_pi.s_pi.ms_gyroX_rads = IMU.getGyroX_rads(); u_pi.s_pi.ms_gyroY_rads = IMU.getGyroY_rads(); u_pi.s_pi.ms_gyroZ_rads = IMU.getGyroZ_rads(); u_pi.s_pi.ms_getMagX_uT = IMU.getMagX_uT(); u_pi.s_pi.ms_getMagY_uT = IMU.getMagY_uT(); u_pi.s_pi.ms_getMagZ_uT = IMU.getMagZ_uT(); u_pi.s_pi.ms_vl53l0x = capteur0.readVl53l0x(); //On lit et stock les données Serial1.write (u_pi.cast_pi, sizeof u_buf.cast_pi); }
PI
main.cpp
#include <iostream> //Permet d'utiliser In et Out du moniteur série #include "rs232.h" //Librairie de communication RS232 #include "comPI.h" //Communication de la PI vers ESP32 #include "algo.h" using namespace std; int main () { F_COMPORT(); //test de la lib RS232 MadgwickSetup(); while(1) { piReceive(); //RadToDeg(); //EulerAngleAccel(); //RollPitchYaw(); usleep (100000); //0.100s = 100ms //50000 = 0.050 } return 0; }
comPI.cpp
#include <iostream> //Permet d'utiliser In et Out du moniteur série #include <iomanip> //setprecision #include "rs232.h" //Librairie de communication RS232 #include "comPI.h" #include "MadgwickAHRS.h" //#include "algo.h" using namespace std; union U_DATA u_esp; union U_DATA u_buf; float aX, aY, aZ, gX, gY, gZ, mX, mY, mZ; int cport_nr(0); // 0 = ttyS0 ls /dev/tty* int bdrate(115200); // Baud char mode []={'8','N','1',0}; // 8 data bits, no parity, 1 stop bit struct S_CONNECTION { char ms_connection; }; //Test du port de communication void F_COMPORT() { if (RS232_OpenComport(cport_nr, bdrate, mode)) { cout <<"-----> Ne peut pas ouvrir le port com.\n \n"; } else { cout << "-----> Port de communication ouvert PI. \n \n"; piOkSend(); piOkReceive(); } usleep (100000); //0.100 s } void S_ESP::affiche() const { //On regarde ce qu'Arduino nous envoit cout << "Pi reçoit u_esp.s_arduino.ms_vl53l0x :\t " << u_esp.s_esp.ms_vl53l0x <<" \n"; //cout <<fixed << setprecision(6); cout << "Pi reçoit u_esp.s_esp.ms_accelXYZ_mss :\t " << u_esp.s_esp.ms_accelX_mss <<"\t" << u_esp.s_esp.ms_accelY_mss <<"\t" << u_esp.s_esp.ms_accelZ_mss <<"\n"; cout << "Pi reçoit u_esp.s_esp.ms_gyroXYZ_rads :\t " << u_esp.s_esp.ms_gyroX_rads <<"\t" << u_esp.s_esp.ms_gyroY_rads <<"\t" << u_esp.s_esp.ms_gyroZ_rads <<"\n"; cout << "Pi reçoit u_esp.s_esp.ms_MagXYZ_uT :\t " << u_esp.s_esp.ms_MagX_uT <<"\t" << u_esp.s_esp.ms_MagY_uT <<"\t" << u_esp.s_esp.ms_MagZ_uT <<"\n"; } //-----On recoit les données de l'esp void piReceive () { //Récupère un tableau de données de la pi dans le buffer envoyé d'Arduino //Via la RS232 int n = RS232_PollComport(cport_nr, u_esp.cast_esp, sizeof (u_buf.cast_esp)); cout << "----- \n"; cout << "Taille sizeof u_buf.cast_esp : " << sizeof (u_buf.cast_esp) << " octets/bytes. \n"; if (n > 0) //(n >= sizeof (u_buf.cast_arduino)) //if (n > 0) { u_esp.cast_esp[n] = 0; cout <<"Pi reçoit d'Esp : "<< n <<" bytes. \n"; } aX = u_esp.s_esp.ms_accelX_mss; aY = u_esp.s_esp.ms_accelY_mss; aZ = u_esp.s_esp.ms_accelZ_mss; gX = u_esp.s_esp.ms_gyroX_rads; gY = u_esp.s_esp.ms_gyroY_rads; gZ = u_esp.s_esp.ms_gyroZ_rads; mX = u_esp.s_esp.ms_MagX_uT; mY = u_esp.s_esp.ms_MagY_uT; mZ = u_esp.s_esp.ms_MagZ_uT; u_esp.s_esp.affiche(); }
#ifndef DEF_GCOM #define DEF_GCOM //On reçoit les données ESP struct S_ESP { float ms_accelX_mss; //4 octets/bytes (32 bits) : float ms_accelY_mss; float ms_accelZ_mss; float ms_gyroX_rads; float ms_gyroY_rads; float ms_gyroZ_rads; float ms_MagX_uT; float ms_MagY_uT; float ms_MagZ_uT; unsigned short int ms_vl53l0x; //2 octet/bytes (16 bits) : 0 / 65 535 void affiche() const; }; //Union pour l'envoie, la réception et la gestion des paquets union U_DATA { S_ESP s_esp; unsigned char cast_esp[sizeof (s_esp)]; }; extern U_DATA u_esp, u_buf, u_epaper; void F_COMPORT(); void piReceive(); #endif//-----DEF_GCOM
Merci ^^
EDIT : c'est ce que j'ai fais en commentant petit à petit et ça ne change rien.
#959
Posté 29 août 2019 - 12:06
Enlève le usleep (100000); du main du Pi.
Si tu demande au Pi de ne rien faire pendant 100ms après chaque lecture, alors il est impossible de faire une lecture toutes les 100ms, vue que la lecture elle même prend un peu de temps (disons 1ms), donc au mieux tu fera une lecture toutes les 101 ms : du coup, tu prendras 1ms de retard à chaque lecture, du coup au bout de quelques dizaines de minutes, tu finira par accumuler un retard de plusieurs secondes.
Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...
Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.
#960
Posté 29 août 2019 - 01:12
Dans tout les cas il devrait être interdit de forcer des calculateurs à dormir ou bien à attendre au lieu de calculer x)
On devrait bannir les fonctions delay usleep et autre ! x)
Si mon commentaire vous a plus laissez nous un avis !
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 !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être !
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!
1 utilisateur(s) li(sen)t ce sujet
0 members, 1 guests, 0 anonymous users