Aller au contenu


Contenu de R1D1

Il y a 991 élément(s) pour R1D1 (recherche limitée depuis 12-juin 13)



#90714 Glenn Robot Humanoide

Posté par R1D1 sur 07 décembre 2017 - 02:50 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Coucou les Maker's, bon je suis toujours la façon de faire communiquer Pi et Arduino en C++, d'après les conseils de plusieurs makers et de passer par un Convertisseur logique pour être en Tx/Rx, j'ai donc acheté se produit Boutique le hic c'est que j'ai peur de faire une mauvaise manip, voici mon branchement, et sans savoir réellement si cela va fonctionner par la suite : 
 
Lv : 3.3 Pi
Hv : 5.0 Mega (arduino)
Lv1 : Tx Pi
Lv2 : Rx Pi
Hv1 : Rx Mega
Hv2 : Tx Mega


N'oublies pas la masse (GND) ! Une tension est une différence de potentiel, quand tu branches le pin d'une carte à quelque chose (e.g. un capteur) et que tu mets ce pin (e.g.) à HIGH, tu mets ce pin à un certain potentiel, qui, comparé au potentiel de la masse, devient une tension (5V, 3.3V, etc.).
Pour que ce circuit puisse convertir correctement les niveaux, il faut qu'il puisse comparer le potentiel imposé sur les branches LV/HV avec une référence, la masse.

Si je comprends bien le circuit (voir ce lien, si tu peux au moins mettre la référence du composant sur la boutique, Mike ? : https://www.generati...l-sparkfun.html), tu as 4 "ponts" pour convertir 4 signaux. Comme tu veux TX et RX, il faut effectivement utiliser 2 de ces 4 paires de pins.

Le design de Glenn est de plus en plus classe ! Je trouve qu'il gagne son identité propre plus tu avances !



#90897 Glenn Robot Humanoide

Posté par R1D1 sur 15 décembre 2017 - 11:17 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Coucou les Maker's, peut on faire de la POO avec arduino ??
 
Si oui, il y a t'il une méthode particulière, ou cela se comporte t'il comme pour du C++ ??
 
Edit : j'ai trouvé ça, je ne sais pas si la piste est bonne.
http://www.vorobotics.com/wiki/index.php?title=Adafruit-multi-tasking-the-arduino-part-1
 
Merci

Oui, tu utilises la POO à chaque fois que tu crées une instance d'une classe (#include <Servo.h> e.g. Servo cou;), et tu peux définitivement organiser ton code en classes. Le langage Arduino est dérivé du C++ et permet ce genre de choses.



#90341 Glenn Robot Humanoide

Posté par R1D1 sur 24 novembre 2017 - 03:40 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Si j'ai du temps, je testerai la solution de Path sur une nano ce week-end, ça a un peu été la folie ces dernières semaines, et on pourra avoir un échantillon un peu plus large d'essais.



#88941 Glenn Robot Humanoide

Posté par R1D1 sur 17 octobre 2017 - 09:28 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Bon en fait Arobasseb m'a devancé :)

Pour être clair sur ce que je disais : le choix d'un langage ou l'autre dépend de la facilité d'implémentation d'une fonctionnalité. Si python offre une lib de communication super simple, ça peut valoir le coup de réflechir à l'utliser.
Mais dans ton cas, si tu veux rester avec C++, et surtout pour une fonctionnalité aussi basique que la communication série, pas besoin de python. Je passerai personnellement par l'USB, ce lien (https://www.monocili...sing-usb-and-c/) semble contenir toute l'info nécessaire.
Après, je ne suis pas très au point sur les protocoles de communication, donc c'est ce qui me semble le plus simple. La solution est facile à mettre en place: il faut juste un câble USB. À toi ensuite de définir quelles infos doivent transiter. Il est probablement judicieux de faire des calculs de base sur l'arduino pour simplifier le code côté raspberry (e.g. aggréger toutes les mesures de capteurs à un temps t donné et tout renvoyer à une fréquence paramétrable vers le Pi, faire les boucles d'asserv les plus basique sur l'arduino directement).
J'ai pas le temps de tester en pratique avant ce week-end je pense, mais je peux essayer ce lien (comm USB) d'ici dimanche.



#88418 Glenn Robot Humanoide

Posté par R1D1 sur 06 octobre 2017 - 10:26 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

4 vols, 6h30 et 2100€.
Mes cours sont gratuits si tu offres le voyage et l'hébergement :D



#90906 Glenn Robot Humanoide

Posté par R1D1 sur 15 décembre 2017 - 03:23 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

A priori ton lien suffit, si tu veux un exemple de code très simple (sans garantie de compilation ou fonctionnement réel parce que c'est vieux), tu peux regarder (auto-promo) mon repository robOStique : https://github.com/r1d1/robOStique(en anglais).
J'avais commencé à organiser en classe du code écrit et/ou tiré des exemples que j'avais pu trouver ça et là.
En plaçant ce code dans le dossier "librairies" de l'IDE, tu peux ensuite faire un " #include <robOStique.h> " (ou en remplaçant < > par " " si ça marche pas) et avoir accès à toutes les classes ainsi déclarées.
Tu pourrais par exemple embarquer le code qui fait la communication série côté Arduino dans une classe, puis dans ton sketch principal, créer un objet de cette classe et l'utiliser (init, update, ...).



#90917 Glenn Robot Humanoide

Posté par R1D1 sur 15 décembre 2017 - 06:09 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Si ta librairie est petite, tu peux tout avoir dans un fichier, mais en général, mieux vaut avoir un fichier cpp/h par classe. Quitte à avoir un fichier header qui regroupe les headers des fichiers individuels, e.g. :
// Sensors.h
// ---------
#include "Ultrasound.h"
#include "IR.h"
// ...
donc pas comme je l'ai fait dans ma librairie :D
Je n'ai pas testé l'influence sur la taille du code, mais il est probablement plus économique de pouvoir faire ' #include "sensors/distance/Ultrasound.h" ' que ' #include "sensors.h" ' et de rajouter tous les prototypes dont on a pas besoin.

Comme je le disais sur Discord, l'utilisation des pointeurs et l'organisation en classes sont des outils différents (et complémentaires).



#103350 Glenn Robot Humanoide

Posté par R1D1 sur 08 mai 2019 - 02:32 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Salut les Maker's, je me posais la question de savoir si le HC-SR04 serait l'idéal pour la détection d'obstacles d'après vous ?

Je l'ai placé sur Glenn pour voir avec sont cône de détection...
 
Ou alors existe t'il un autre moyen de détecter des obstacles sur un champ plus large ?

Le truc qui m'aurait plu et la projection de points pour obtenir un certains relief de se que le robot peu détecter (chose que j'aimerais bien pouvoir intégrer au niveau de la cam de Glenn).
 
(...)


Pour faire plaisir à Mike (désolé si le propos est un peu mélangé, c'est une transcription feignante de ma réponse sur le Discord) ;) :

Si tu veux juste mesurer la distance au sol/vers l'avant (pour détecter un obstacle) un seul capteur est en général suffisant. Le robot ne saura pas ce qu'il a sous les pieds à ce moment, mais comme le capteur regarde devant lui, il aura toujours l'info de s'il y a un trou là où il va aller.

Par contre, ce genre de capteur (HCSR04, VLX, infrarouge, etc ...) donne une mesure ponctuelle (pas exactement, mais c'estce qu'on suppose), dans une direction theta. Donc pour avoir une mesure dans la direction theta+1°, il faut ré-orienter le capteur/le robot, ou mettre plusieurs capteurs fixes dans des directions différentes en faisant attention à ce qu'ils n'aient pas d'interaction (e.g. ultrason ou infrarouge). Pour avoir tester un capteur US monté sur un servo sur Froggy (voir ici: https://www.youtube....h?v=w7kXEE_CMCU), je recommande les multiples capteurs fixes, parce que faire tourner le servo, faire une mesure et recommencer, c'est long par rapport à la vitesse de commande des moteurs, et si le robot bouge pendant ce temps, on ne sait plus vraiment dans quelle direction réelle la mesure est faite. Avec deux capteurs, on a juste à les lire pour avoir deux infos cohérentes.
La version ultime de la première option (qui résout le problème que j'évoque), ce sont les lasers rotatif type RPLidar, Hokuyo LX30, qui font tourner un capteur ou un miroir très vite à 360° pour avoir un profil dans toutes les directions.
Ces capteurs mesurent dans le plan orthogonal à l'axe de rotation, si tu veux mesurer tout l'espace devant le robot, il faut faire tourner le capteur sur lui-même (pour mesurer dans le plan) puis dans la troisième direction (orthogonale au plan de rotation).
La solution "cheap" (mais très lente), c'est d'avoir un capteur HCSR04 sur une tourelle pan-tilt. Une phase de mesure revient à positionner les servos dans toutes les combinaisons d'angles voulues et faire une mesure de distance avec le capteur. Mais attention, même problème que j'évoquais plus haut: si le robot bouge avant d'avoir fini un scan, les données seront incohérentes.
Solution alternative: utiliser une camera type Kinect qui te renvoie directement l'image et l'image de profondeur de là où vise la caméra. Voir Xtion, Intel Realsense pour des capteurs similaires.
Bien évidemment le prix augmente en conséquence :)

[href^="http://www.roboform.com/php/land.php"]
{display:none !important;}



#98268 Glenn Robot Humanoide

Posté par R1D1 sur 08 août 2018 - 02:01 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Ho !
Glenn vient de passer de concept à réalité ! ;)



#91155 Glenn Robot Humanoide

Posté par R1D1 sur 28 décembre 2017 - 05:02 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Fizz Oliver !
Pas sûr de comprendre complètement ce que tu envisages.
Pour utiliser le capteur, il faut un programme qui gère l'interaction avec le matériel. Par exemple, le code sur l'arduino qui lit les pins du capteur ; c'est le driver du capteur. Sur l'arduino, tu peux avoir plusieurs capteurs branchés et au lieu de lire les données de chacun, ne lire que certains.
Mais ne pas lire certains pins n'a probablement pas beaucoup d'influence sur la conso. L'arduino peut également gérer l'alimentation du capteur, et dans ce cas, tu peux certainement économiser de l'énergie.
Si tu gères ton capteur directement avec la Pi et un programme dédié, la solution est de quitter le programme à certaines conditions (en gros, arriver à la fin du main). Mais dans ce cas, il faut que tu fasses communiquer le programme principal et le programme qui gère le capteur.
Pour le coup, ROS est bien pratique pour ça. :)



#90932 Glenn Robot Humanoide

Posté par R1D1 sur 16 décembre 2017 - 01:29 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Quel est le problème d'avoir plusieurs classes ?
Du moins, y a t'il un problème à avoir plusieurs classes pour un capteur si il y en a besoin ?
 
Hum, bien compris sur cette ligne : "Je n'ai pas testé l'influence sur la taille du code, mais il est probablement plus économique de pouvoir faire ' #include "sensors/distance/Ultrasound.h" ' que ' #include "sensors.h" ' et de rajouter tous les prototypes dont on a pas besoin." cela inclut quoi au juste ?

J'ai pas compris tes questions ^^
Pour un capteur (matériel que tu branches sur ta carte), tu écris une classe qui te permet de le gérer facilement le capteur : sortir la valeur mesurée, faire des calculs simples dessus, initialiser les pins, etc.
En général, une classe devrait suffire :le principe de la POO, c'est que chaque classe a une fonction définie (e.g. gérer le capteur). Si une classe commence à tout faire, on appelle ça un "God object" (https://fr.wikipedia...wiki/God_object), c'est un mauvais design du code. À éviter si possible.

Pour "#include ...", je donne juste des exemples pour illustrer différentes organisations du code, ce qu'il y a vraiment dans les fichiers, ça dépend de tes besoins avec le capteur.



#87769 Glenn Robot Humanoide

Posté par R1D1 sur 19 septembre 2017 - 01:10 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Ahah, je suis en train de travailler sur un design pas si éloigné pour Froggy (inspiration Briaeros d'Appleseed, Chappie, XCOM2 Advent MEC, Warhammer 40k Tau Exo-armure ...) :)

 

Par contre j'ai pas de bonne référence de HP :/




#86507 Glenn Robot Humanoide

Posté par R1D1 sur 07 août 2017 - 12:19 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Ok, c'est la régression total, je recherche la commande pour down dossiers, ou fichiers via raspbian pour github, (un vrai boulet), j'ai complétement oublié et impossible de retrouver la commande via google. :'(
 
Ou alors truc simple je fais un copier coller du code dans un nouveau fichier ? (cpp et h).
 
Je repars de 0 et ça me déprime :'( snif


Tu veux dire pour récupérer des fichiers depuis un repository git distant (par exemple sur github) ? En général, on parle de "cloner un repository" (ohh le franglish), et la commande correspondante est :
git clone <adresse_du_repo.git>
Sur github, tu as également un bouton vert sur la page du repository qui t'intéresse marqué "Clone or download" pour avoir l'adresse.



#84400 Glenn Robot Humanoide

Posté par R1D1 sur 05 juin 2017 - 08:52 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Here I am !

En effet, dans mon exemple, je considère un bras simplifié avec un seul DOF par articulation (dans le cas 2D ça marche très bien). Ce que tu proposes me semble pas mal, peut-être même que tu peux placer "segment" directement au niveau du bras. Du coup, ton bras serait une liste d'articulations et de segments qui les connectent.
Par contre, je ne suis pas sûr de ce que tu veux dire par "faire la liaison" ni pourquoi tu parles d'héritage. L'héritage sert quand tu veux spécialiser un objet: la classe école hérite de la classe bâtiment, parce que l'ensemble des écoles est inclus dans l'ensemble des bâtiments. Si tu veux créer une ville, tu ne dois pas faire hériter chaque bâtiment de la classe Ville mais avoir une liste de Bâtiments dans la classe Ville.

Un truc qui est resté un peu flou jusqu'ici (mais j'imagine que tu as travaillé ça de ton côté), c'est de définir un bon modèle du bras : dessiner les différentes parties, placer correctement les référentiels (avec une convention de Denavit-Hartenberg par exemple), lister les différentes variables : angles, longueurs, etc. qui rentrent en jeu dans les calculs. Une fois ces choses explicites, si tu écris les étapes à suivre et quelles variables entrent en jeu pour faire bouger le bras, tu auras une vue de ce que ton programme doit faire.

Il faut bien comprendre que toutes les classes que tu crées en amont pour organiser ton code, le but est de les utiliser ensuite pour contrôler le robot. Il faudra effectivement déclarer une fois les objets du type que tu veux (Articulation, Servo, etc.), mais ensuite, pour contrôler ton robot, tu as juste besoin d'appeler leurs méthodes.
Ça devrait se retrouver dans le main.py parce que c'est ce code là qui va tourner à la fin sur ton robot. En gros, toutes tes définitions et implémentations de classes vont dans des fichiers que tu importes ensuite dans ton programme principal de contrôle. Ton fichier "main.py" doit être spécifique à ton robot, les modules que tu écris devraient (en théorie) pouvoir être utilisés sur n'importe quel robot, indépendemment de sa morphologie.



#85665 Glenn Robot Humanoide

Posté par R1D1 sur 11 juillet 2017 - 10:15 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Vim :)

Sincèrement, ça peut valoir le coup de commencer le C++ avec un éditeur de texte basique pour bien comprendre la compilation et l'édition de liens. Une fois que tu as bien compris cela, tu peux utiliser un éditeur qui fait toutes ces choses pour tio (Qt Creator, Eclipse, etc.).

Je ne dirais pas que le C++ c'est simple, mais ton expérience en Python va te servir : la programmation orientée objet (POO) est une composante importante du C++, donc les principes que tu as déjà acquis vont t'aider. Et pour ceux que tu n'as pas encore compris, les revoir dans un autre langage est une bonne chose pour prendre un peu de recul. De mémoire, le cours d'OpenClassRoom (le SdZ, quoi :D ) est plutôt bien sur ce sujet.

 

Courage ! Et comme d'hab, n'hésites pas à poser tes questions :)

 

PS : pour vim, je plaisante, il est assez compliqué à prendre en main, pas besoin de se rajouter en plus cette difficulté.




#84155 Glenn Robot Humanoide

Posté par R1D1 sur 29 mai 2017 - 08:13 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Ça m'a l'air pas mal tout ça (je réponds vite, j'ai pas trop de temps en ce début de semaine).
Pour ta classe Bras, tu peux avoir un attribut self.articulations et un attribut self.longueurs, puis ton code un peu comme ça :
 
import toutesMesSuperLibrairiesQuiFontLeCafe as tmslqfc

class Bras():
  def __init__(self, name):
    self.name = name
    # On crée nos listes, vides pour l'instant 
    self.articulations = []
    self.longueurs = []
    self.nb_articulations = 0

  def addArticulation(self, servo):
    self.articulation.append(servo)
    self.nb_articulations += 1

  def addOs(self, l):
    self.longueurs.append(l)

  def IK(self, pos):
    # calcule les angles des servos étant donné la position à atteindre et la géométrie du bras
    tmslqfc.IKSolver()
    return angles

  def goTo_cartesien(position):
    # position est un tuple en 2 ou 3D
    angles = IK(position)
    s = self.articulations # parce que j'ai la flemme d'écrire self.articulations à chaque fois
    for i in np.arange(len(self.articulations)):
      #s[i] est un objet Servo
      s[i].envoiangle(angles)
import numpy as np
import toutesMesSuperLibrairiesQuiFontLeCafe # juste pour invoquer magiquement les bouts de code que j'ai pas envie d'écrire :)

# On crée les servos avec leurs paramètres en dur dans le code (les lire depuis un fichier de config est une bonne option aussi)
servoepgy = Servo (9, 0, 340, 94, 537, 225)
servocogy = Servo (8, 0, 180, 100, 515, 180)
servopogz = Servo (4, 0, 180, 100, 515, 180)

# on crée un bras qui est une instance de la classe Bras
brasDroit = Bras()
# On peut ajouter un servo au bras directement ...
brasDroit.articulations.append(servoepgy)
# ... mais la manière "propre" permet de faire d'autres updates dans "Bras" si nécessaire (ici, le nb_articulations)
brasDroit.addArticulation(servocogy)
brasDroit.addArticulation(servopogz)
lesOsDuBras = [0.7, 0.6] # deux barres de 70 et 60 cm
for o in lesOsDuBras:
   brasDroit.addOs(o)

# On envoie une position cartésienne à atteindre et le bras calcule les angles à appliquer 
brasDroit.goTo_cartesien((0.3,0.5))
Ce bout de code ne fonctionne probablement pas, mais c'est pour te montrer très grossiérement comment on peut faire avec une classe "Bras", et une liste de Servo. Parmi les choses qui ne sont pas explicités du tout ici, il y a la question des repères attachés aux articulations pour pouvoir calculer la cinématique inverse. Je me souviens que j'avais promis un tuto sur tout ça en début d'année, heureusement, vous ne m'avez pas attendu pour progresser :).



#83887 Glenn Robot Humanoide

Posté par R1D1 sur 21 mai 2017 - 12:57 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

N'hésite pas à poser tes questions si des choses ne te semblent pas claires, et à montrer ton code de temps en temps :)
Je suis loin de maîtriser tous les rouages de python, mais au moins, ça me poussera à reformuler ce que je connais !



#83867 Glenn Robot Humanoide

Posté par R1D1 sur 20 mai 2017 - 09:38 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Here I am !

Quand ton code commence à grossir, c'est effectivement une bonne chose de séparer le code principal et les différents composants qui vont servir. En python, on peut créer des modules, que l'on peut ensuite importer dans d'autres scripts.

Il faut faire la différence entre le programme que tu fais tourner sur ton robot (pp.py, on peut l'appeler aussi main.py) et les fichiers python de tes modules. La différence principale, c'est que pp.py contient une fonction main, ou au moins, produit un effet (commander les moteurs, traiter du texte, afficher des images, etc.), tandis que les autres fichiers n'auront que des définitions de fonction ou de classe. Si tu fais "python fichiermodule.py", rien ne doit se passer (en dehors d'éventuels tests, mais je ne rentre pas dans les détails).
Pour ces fichiers modules, l'intérêt de faire de la programmation orienté objet (POO, c'est à dire déclarer et manipuler des classes), c'est que tu vas associer au sein d'un même objet les données et méthodes.
Tu peux donc définir une classe qui gère un servo, puis créer autant d'objets de cette classe que tu as de servos à commander. Quelques attributs/méthodes utiles : le pin de commande du servo, l'angle actuel (mesuré de préférence, dernière commande sinon ?), un angle de "repos" (position initiale), une méthode appliquerAngle(angle_but), une méthode retourInit pour revenir en position de repos, une qui gère la vitesse, etc.
Pour gérer la cinématique/dynamique, tu peux par exemple créer des classes "Jambes", "Bras", qui permettent de contrôler plus facilement tes servos. Par exemple, une classe Bras pourrait avoir un attribut qui est une liste d'objets Servo, une liste de longueurs pour les différents segments du bras, une méthode "calculCinematiqueDirecte" et une "calculCinematiqueInverse" qui font les calculs pour passer de l'espace articulaire à l'espace cartésien et vice-versa, une méthode "atteindre" qui envoie effectivement les commandes aux servos.
Pour les méthodes de cinématique directe et inverse, tu peux créer une classe DKSolver (Direct Kinematic Solver) et IKSolver qui implémentent les calculs pour un nombre N d'articulations ...

Dans tous les cas, n'hésite pas à créer autant de fichiers python différents que tu le juges nécessaire pour avoir une bonne lisibilité de ton code. Une bonne pratique en général : une classe a un rôle particulier. Si deux méthodes d'une classe n'ont rien à voir, il faut probablement diviser la classe existante en deux.
Tous tes fichiers, tu peux les regrouper dans un dossier avec le nom que tu souhaites (e.g. monsupermodule) dans lequel tu mets un fichier nommé __init__.py vide. En ajoutant le dossier qui contient "monsupermodule" à la variable d'environnement $PYTHONPATH, tu devrais pouvoir faire "import monsupermodule" dans n'importe quel autre fichier (donc par exemple dans pp.py) sur la Raspberry.
Et une fois que tu as fais cet import, tu peux créer des objets que tu auras défini précédemment. À noter que je ne maîtrise pas très bien cette notion de modules dans python, et j'ai toujours tendance à bricoler un peu pour que ça marche correctement. Tu peux ausi chercher du côté des "egg" et "wheel" en python, ça permet de créer des packages proprement.
Dernière précision, j'utilise python 2.7, donc il est possible qu'il te faille adapter des choses à python 3 le cas échéant.



#85685 Glenn Robot Humanoide

Posté par R1D1 sur 11 juillet 2017 - 02:26 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Ça fait plaisir de voir que tu t'y mets !! D'accord avec R1 pour l'éditeur. Prends un qui colorise comme atom ou sublime text. Les 2 tournent sur ton raspberry. ;)

J'ai hésité à citer ces deux là qui sont vraiment pas mal, mais je ne sais pas ce qu'ils fournissent en termes d'aides à la  programmation (genre sous Qt Creator, tu as des raccourcis pour naviguer entre implémentation et définition, sauts vers les définitions de fonction, etc. qui sont vraiment pas mal). Tu sais s'il y a ce genre d'outils pour ces deux éditeurs (j'ai utilisé Atom pour python mais juste comme éditeur texte perso) ?




#85743 Glenn Robot Humanoide

Posté par R1D1 sur 12 juillet 2017 - 08:16 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Hein!!?? C'est quoi ça????

 

Par exemple un pointeur qui n'est pas libéré.


Pour être exact, en C/C++, la gestion de la mémoire est potentiellement plus explicite qu'en python. Quand on déclare une variable qui est destinée à contenir un tableau, il faut réserver l'espace en mémoire pour stocker les données.
Si c'est fait de manière statique, pas de problèmes, exemple:
 
float mesComptesEnBanque[5];
mesComptesEnBanque[2] = -500.0; // :(
mesComptesEnBanque[4] = 1000; // \o/
mais on ne connaît pas toujours la taille des données qu'on veut stocker au début, il peut donc être nécessaire de passer par un pointeur pour initialiser dynamiquement l'espace mémoire:
float * mesComptes;
mesComptes = new float[<taille_récupérée_en_argument>];
Dans ce cas, la variable qui est déclarée est un pointeur sur la zone mémoire (l'adresse de cette zone, où plus imagé, l'adresse de notre entrepôt qu'on loue pour stocker nos bidules), mais quand on sort du bloc où cette variable a été déclaré (chercher : portée des variables en c++), seul le pointeur est supprimé, pas la mémoire allouée. En gros, on oublie l'adresse de l'entrepôt, mais on a oublié de stopper la location de l'espace. Du coup, cette mémoire reste bloquée et non utilisable par le système (à ma connaissance il n'existe pas de moyen de récupérer cette mémoire à par redémarrer l'ordi, mais je me trompe peut-être).
Pour éviter ça, chaque part de mémoire allouée dynamiquement doit être désallouée avec delete avant que son adresse ne soit perdu (je vous laisse chercher ça, pas le temps de développer plus maintenant).

EDIT : grillé par arobasseb !



#85983 Glenn Robot Humanoide

Posté par R1D1 sur 18 juillet 2017 - 11:14 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Hummm pas tout compris, enfin plus ou moins.
 
Dans le .h c'est le prototype que tu déclares (je reprend le nom prototype comme dans le cour), ensuite je définis ma fonction dans un autre fichier si besoin, ça je crois que j'ai compris ^^
Ce que tu dis lorsque tu déclares c'est le prototype ?
 
Mouais je vais bien voir de toutes façons, petit à petit comme on dit...
 
PS : déjà que le C++ n'est pas évident, mais alors voir le processus de tous ce que tu m'a expliqué en anglais c'est pire lol ^^
Sachant que l'anglais et moi c'est moyen..

C'est ça : le prototype te permet de déclarer ta fonction. Évidemment, tu verras tout étape par étape. Pour bien comprendre le C++, je pense qu'il est important de bien comprendre le processus de compilation (que font le préprocesseur, le compilateur, le compilateur pendant l'édition de liens, etc.). Ça justifie pas mal pourquoi on fait certaines choses en C/C++.
 

(...)
Et c'est sans utiliser les trucs dont je n'ai pas besoin en C : allocation dynamique de mémoire entre autre.
(...)
 
Je n'ai jamais vraiment compris les concepts qui se cachent derrière les langages orientés objet, et ça ne m'intéresse pas trop, tant que j'arrive à coder ce que je veux. Mais j'avoue que parfois, quand je dois me plonger dans du code déjà écrit en C# ou C++, j'ai vraiment du mal... Beaucoup de mal.
(...)

Tu n'as jamais eu besoin de faire un malloc après avoir déclaré un pointeur en C ? Non pas que ça soit obligatoire, mais ça peut être bien pratique (ne serait-ce que pour avoir du code flexible qui s'appuie sur un fichier de config sans besoin de tout recompiler à chaque fois).
Je trouve personnellement le concept d'objet assez merveilleux en terme d'organisation propre du code. Ça permet de poser des limites assez claire entre quel bout de code fait quoi, là où une approche par fonction manque de hiérarchie (c'est mon point de vue en tout cas).
Après, pour des projets persos où le code est très spécialisé et unique, ça n'est pas forcément nécessaire, mais pour réutiliser du code interprojets, c'est super pratique. (il y aurait sûrement moyen de faire la même chose avec des fonctions, mais ... l'objet, c'est beau ! :P )



#85966 Glenn Robot Humanoide

Posté par R1D1 sur 18 juillet 2017 - 04:19 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Parce que ta fonction ne sera pas toujours dans le même fichier.

En C++, on sépare en général la déclaration de la définition/implémentation. On écrit un fichier header en .h dans lequel on déclare les classes, les fonctions que l'on veut créer, puis on définit/implémente ces classes dans des fichiers .cpp. En quelque sorte, le fichier header indique ce qui est disponible, le fichier cpp indique comment ce qui est disponible fonctionne.

Comme en python, tu peux vouloir séparer ton code en "programme principal" et "outils". Par exemple, dans le code que tu postes, tu fais appel aux flux d'entrée/sortie standards (le flux de sortie ici), mais tu n'as pas implémenté la classe qui te permet de faire ça. À la place, tu as fais un "#include <iostream>" qui signifie "cherche dans les emplacements standards le fichier header iostream.h (ou .hpp) et inclus le ici". Ce fichier contient toutes les déclarations de ce que tu peux faire (les fonctions, etc. disponibles). Cela suffit au compilateur pour reconnaître ce symbole dans ton code (quand tu appelles cout) et savoir que ce bout de code doit être complété plus tard, lors de l'édition de liens.

 

Pour résumer (quand je dis "fonction" dans le texte suivant, comprendre "fonctions, classes, etc.") :

- soit tu déclares et définis toutes tes fonctions avant le code où elles sont appelées. Dans ce cas, il me semble que le prototype n'est pas nécessaire.

- soit tu déclares tes fonctions avant le code qui y fait appel et tu les définis après. Dans ce cas, tu dis au compilateur : "t'inquiète copain, ma fonction nombreDeSecondes que j'utilise dans main() n'est pas un symbole inconnu, c'est définis ailleurs".

- soit tu définis ton code dans un autre fichier, tu le déclares dans un fichier header, puis tu inclus ce dernier dans ton fichier principal pour que le compilateur sache que les fonctions que tu appelles ensuite ne sont pas des erreurs de syntaxe / symboles indéfinis.

- Et non, on n'inclue pas directement les fichiers .cpp, une bonne explication du processus en anglais ici : https://softwareengi...luding-only-the




#85957 Glenn Robot Humanoide

Posté par R1D1 sur 18 juillet 2017 - 01:57 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Pour ça : https://benchmarksga...thon3&lang2=gpp

:P

 

Python est plus facile d'accès que C++, clairement, et pour beaucoup de tâches, c'est suffisant. Mais d'expérience, quand tu as besoin de faire tourner 10 réplications d'une expérience avec 10 variations de 3 paramètres (soit un total de 10000 expériences), tu es content que ton expérience puisse être calculée 10 à 100 fois plus vite. Exemple, répéter 10000 le test fannkuch-redux du lien prendrait 55,99 jours avec du code python et seulement 1,19 jour avec du code c++ (28,75 heures). Si l'algorithme et/ou les données le permettent, en parallélisant les calculs, tu peux même faire tomber ce temps à quelques heures contre quelques jours en python.

Dans le cas d'un robot, la raison est plutôt au niveau de la fréquence d'exécution. Un algorithme critique (ou en tout cas, important) doit pouvoir tourner en moins de temps que la boucle de contrôle. Exemple : déterminer les obstacles à partir d'une image de profondeur (type Kinect) ou de deux images en stéréo. Une boucle de contrôle à 50 ou 100 Hz demande que le processus de traitement d'image soit inférieur à 10 à 20 ms. Du coup, la moindre optimisation est bonne à prendre, et celle du choix du langage tombe sous le sens.




#85772 Glenn Robot Humanoide

Posté par R1D1 sur 12 juillet 2017 - 02:37 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

Ok, je crois avoir compris, libérer la mémoire avec des variables inutiles dans certains cas pour éviter une saturation qui pourrait nuire au programme, j'espère que dans le cours d'OpenClassRooms ils en parlent, je vais bien voir, par contre c'est vicieux le C++...

Pas tout à fait. Les variables "inutiles" ne restent pas : la fin d'un bloc (fermeture d'une accolade : " } ") supprime les variables qui étaient déclarées après l'accolade ouvrante ( " { " ) : c'est le mécanisme de portée des variables. Le problème vient quand on supprime des pointeurs : on supprime juste l'accès à la mémoire, mais on ne libère pas la mémoire en question. Quand le programme quitte, des données pointées par "mesComptes'" dans mon exemple au dessus sont toujours en mémoire, et il n'y a plus de moyen d'y accéder. Même si on relance le programme, on fait autre chose, etc. La fuite de mémoire nuit à l'ordinateur en entier, pas juste ton programme.




#76219 Glenn Robot Humanoide

Posté par R1D1 sur 11 novembre 2016 - 11:49 dans Robots à pattes et jambes, humanoïdes, bipèdes, quadrupèdes, hexapodes ...

A ce niveau tout dépend du but recherché et du budget.

  • Si c'est juste pour tourner la tête en direction de la baballe rouge ou suive un visage, une simple webcam suffit, c'est (pratiquement) gratuit.
  • Si c'est pour éviter les obstacles à l'intérieur, un petit capteur TOF monté sur tourelle ou mieux une caméra TOF fera le job mais le budget n'est plus le même
  • Si c'est pour se repérer et cartographier l'environnement en 3D, on s'oriente vers un LIDAR simple (une seule ligne) et un plus gros budget. Ou un LIDAR à 64 faisceaux pour le prix d'une voiture.
Les sous...hélas toujours les sous ...  :kez_13:

La kinect (et ses clones) fournit une image couleur et nuage de point 3D pour pas si cher que ça (comparé aux autres produits type LIDAR). C'est certes plus cher qu'une webcam, et il y a une zone morte de détection de la profondeur sur les objets à moins de 40cm, mais il y a de quoi faire (dont du SLAM).