Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

char autonome

Ajout d'une alternative beaucoup moins chère à la référence des conceptions Carter et Kaya à l'aide d'un ensemble Lego EV3.

Dans ce projet, je documenterai la construction d'un véhicule à chenilles fabriqué avec des pièces et des moteurs Lego Technic, amélioré avec LiDAR et contrôlé par une carte Jetson Nano exécutant le dernier SDK Isaac. Aller à la Partie 8 ou 10 pour une démo complète de la navigation autonome.

Le projet comprend les composantes suivantes :

Pourquoi Isaac SDK et pas ROS ?

Pourquoi des pièces Lego ?

Le choix de cette voie soulève certains défis :

PARTIE 1 :Démarrage

1. SDK Isaac

2. Reconnaissance vocale (facultatif)

3. Image Ev3dev

Téléchargez et flashez la dernière image pour EV3 (ev3dev-stretch) sur une carte microSD ou microSDHC. Le format MicroSDXC n'est pas supporté par la brique EV3.

4. Compilateur croisé ARM pour ev3dev

$ sudo apt-get install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi 

Cette partie était particulièrement difficile à configurer correctement. Ubuntu 18.04 (ordinateur hôte et Jetson Nano) utilise GLIBC_2.28 tandis qu'ev3dev utilise Debian stretch et GLIBC_2.24. Tout ce qui est compilé avec la configuration par défaut du compilateur arm-linux-gnueabi-g++ dépendait de GLIBC_2.28 et ne fonctionnerait pas sur EV3. La liaison statique ne fonctionnait pas car quelque chose de plus complexe qu'un bonjour dans le monde provoquait des erreurs de segmentation. La solution que j'ai trouvée était de lier dynamiquement tout sauf la bibliothèque mathématique. Vous pouvez trouver plus d'informations dans le fichier jetson-ev3/toolchain/CROSSTOOL. Une autre solution consiste à utiliser une image docker de Debian 9.

5. Espace de travail Jetson + EV3

$ git clone https://github.com/andrei-ace/jetson-ev3.git 
local_repository(
name ="com_nvidia_isaac",
path ="/home/andrei/ml/isaac"
)
# modifier avec votre chemin vers la chaîne d'outils
linker_flag :"-L/home/andrei/ml/jetson-ev3/toolchain"

6. Connectez Jetson Nano avec EV3

Dans la prochaine partie, je publierai de nombreuses commandes Linux. Parce qu'il y a trois systèmes impliqués, je les posterai exactement comme ils le seraient dans mon terminal, c'est-à-dire :

[email protected] :~/ml/jetson-ev3$ #ceci est exécuté sur mon PC
[email protected] :~$ #ceci est activé Jetson Nano
[email protected] :~$ $ # this in on EV3

Les adresses IP de mon Jetson Nano sont 192.168.0.173 (Ethernet) et 192.168.0.218 (WiFi), donc chaque fois que vous voyez une commande utilisant ces valeurs, remplacez-les par les vôtres.

J'ai utilisé un câble USB A vers mini pour connecter la carte Jetson à la brique EV3 en suivant ces étapes.

Essayez de ssh depuis le tableau Jetson :

[email protected] :~$ ssh [email protected] 

Le mot de passe par défaut est maker.

7. Le tuto ping-pong

Isaac a un tutoriel expliquant un codelet très simple. Je suggère de faire ce tutoriel en premier. Il vous présentera les concepts nécessaires pour créer n'importe quelle application fonctionnant sur Isaac.

Allez maintenant dans le répertoire jetson-ev3/apps/ev3/ping_pong/. Ceci est une version modifiée du tutoriel précédent, avec un petit plus, nous allons envoyer le ping à la brique EV3.

La plupart des fichiers sont familiers du didacticiel précédent. Nous utiliserons Cap’n Proto RPC pour les appels entre Jetson et EV3. Cap'n Proto est largement utilisé pour la communication entre divers composants Isaac, il est donc logique de l'utiliser ici. Pour cela, nous avons besoin de nouveaux fichiers :

Compilez le serveur ev3_pong :

[email protected] :~/ml/jetson-ev3$ bazel build --config=ev3dev //apps/ev3/ping_pong:ev3_pong 

Copiez-le dans EV3 en utilisant scp d'abord sur Jetson, puis sur EV3.

Construisez et déployez l'exemple de ping-pong sur Jetson :

[email protected] :~/ml/jetson-ev3$ /engine/build/deploy.sh --remote_user  -p //apps/ev3/ping_pong:ping_pong-pkg -d jetpack43 -h  

Plus d'informations sur le déploiement et l'exécution de vos applications sur Jetson ici.

Exécutez les deux applications :

[email protected] :~$ ./ev3_pong ev3dev.local:9999
[email protected] :~/deploy/andrei/ping_pong-pkg$ . /apps/ev3/ping_pong

Si tout a fonctionné, vous devriez entendre les messages envoyés par le composant Ping dans le haut-parleur de l'EV3.

8.Contrôler un moteur depuis Isaac

Mêmes principes, juste un peu plus complexes. J'ai utilisé un autre des tutoriels d'Isaac pour interagir avec un moteur EV3 :

Le tutoriel utilise une base Segway RMP. Comme je n'en ai pas qui traîne ou 10000$ pour en acheter un, j'ai créé un pilote qui contrôlera les moteurs EV3 à la place. Le code est ici.

Le serveur qui s'exécute sur EV3 est ici et peut être créé et exécuté avec la commande suivante :

[email protected] :~/ml/jetson-ev3$ bazel build --config=ev3dev //packages/ev3/ev3dev:ev3_control_server
[email protected]:~$ ./ev3_control_server ev3dev.local:9000

J'ai utilisé le joystick virtuel de Sight comme expliqué ici.

9.Base Différentielle pour EV3

Le serveur Ev3ControlServer répondra à 2 appels :

La cinématique est expliquée plus en détail ici et ici.

J'ai utilisé l'exemple d'application proportionnelle_control_cpp pour conduire le robot sur 1 m et rapporter les données d'odométrie de l'EV3 (vitesses linéaires et angulaires) en impulsions rotatives (comptes tachymétriques) par seconde. En utilisant la distance de déplacement calculée (par Isaac) et en mesurant la distance réelle, j'ai trouvé une constante pour ajuster les valeurs rapportées afin qu'elles correspondent aux résultats réels. Cela a bien fonctionné et les résultats étaient reproductibles plusieurs fois et pas seulement en ligne droite. Vous pouvez également calculer ces valeurs en utilisant le rayon de la roue (ou de la piste dans notre cas).

Partie 2 :Construction du robot

La base est très similaire à l'EV3 Track3r de Lego, l'un des modèles officiels du kit EV3 : https://www.lego.com/biassets/bi/6124045.pdf

Le boîtier du Jetson Nano vient d'ici : https://github.com/3D-printable-lego-technic/PELA-blocks

Partie 3 : applications Isaac

Une application Isaac est composée de trois parties principales :

Exemple d'application :

{
"name":"voice_control",
"modules":[
"//apps/ev3/voice_control :voice_control_goal_generator",
"@com_nvidia_isaac//packages/navigation",
"@com_nvidia_isaac//packages/planner"
],
"config_files":[
" apps/ev3/voice_control/model/isaac_vcd_model.metadata.json"
],
"config":{
"2d_ev3.ev3_hardware.ev3":{
"isaac.Ev3Driver " :{
"address":"ev3dev.local",
"port":9000
}
},
"navigation.imu_odmetry.odmetry":{
"DifferentialBaseWheelImuOdometry":{
"use_imu":false
}
},
"commander.robot_remote":{
"isaac.navigation.RobotRemoteControl " :{
"angular_speed_max":0.6,
"linear_speed_max":0.3
}
},
"websight":{
"WebsightServer":{
"webroot":"external/com_nvidia_isaac/packages/sight/webroot",
"ui_config":{
"windows":{
"Voice Command Detection":{
"renderer":"tracer" ,
"dims":{
"width":400,
"height":200
},
"channels":[
{
"name":"voice_control/voice_detection.voice_command_detector/isaac.audio.VoiceCommandConstruction/voice_command_id",
"active":true
}
]
}
}
}
}
},
"navigation.shared_robot_model":{
"SphericalRobotShapeComponent":{
"circles":[
{ "center":[0.0, 0.0], "radius":0.075 },
{ "center":[0.02, 0.03464], "radius":0.055 },
{ "center":[0.02, -0.03464], "radius":0.055 },
{ "center":[-0.04, 0.0], "radius":0.055 },
{ "center":[0.0525, 0.09093 ], "radius":0.035 },
{ "center":[0.0525, -0.09093], "radius":0.035 },
{ "center":[-0.105, 0.0], "radius " : 0,035 }
]
}
},
"navigation.control.lqr":{
"isaac.planner.DifferentialBaseLqrPlanner":{
"manual_mode_channel":"commander.robot_remote/isaac.navigation.RobotRemoteControl/manual_mode"
}
},
"navigation.control.control":{
"isaac.planner.DifferentialBaseControl":{
"manual_mode_channel":"commander.robot_remote/isaac.navigation.RobotRemoteControl/manual_mode"
}
}
},
"graph":{
"nodes":[
{
"name":"voice_control_components",
"components":[
{
"name":"message_ledger",
"type":"isaac::alice::MessageLedger"
},
{
"name":"goal_generator",
"type":"isaac::VoiceControlGoalGenerator"
}
]
},
{
"name":"voice_detection",
"subgraph":"apps/ev3/voice_control/voice_command_detection.subgraph.json"
},
{
"name":"2d_ev3",
"subgraph":"apps/ev3/2d_ev3.subgraph.json"
},

{
"name":"navigation",
"subgraph":"@com_nvidia_isaac//packages/navigation/apps/differential_base_navigation.subgraph.json"
},
{
"name":"commander",
"subgraph":"@com_nvidia_isaac//packages/navigation/ apps/differential_base_commander.subgraph.json"
}
],
"edges":[
{
"source":"voice_detection.subgraph/interface/detected_command" ,
"target":"voice_control_components/goal_generator/detected_command"
},
{
"source":"voice_control_components/goal_generator/goal",
"target" :"navigation.subgraph/interface/goal"
},
{
"source":"2d_ev3.subgraph/interface/base_state",
"target":"navigation. subgraph/interface/state"
},
{
"source":"navigation.subgraph/interface/command",
"target":"commander.subgraph/interface/ control"
},
{
"source":"commander.subgraph/interface/command",
"target":"2d_ev3.subgraph/interface/base_command"
},
{
"source":"2d_ev3.subgraph/interface/flatscan",
"target":"navigation.subgraph/interface/flatscan_for_localization"
},
{
"source":"2d_ev3.subgraph/interface/flatscan",
"target":"navigation. subgraph/interface/flatscan_for_obstacles"
}
]
}
}

Exemple de sous-graphe :

{
"modules":[
"@com_nvidia_isaac//packages/audio",
"@com_nvidia_isaac//packages/ ml:tensorflow"
],
"graph":{
"nodes":[
{
"name":"subgraph",
" composants":[
{
"name":"message_ledger",
"type":"isaac::alice::MessageLedger"
},
{
"name":"interface",
"type":"isaac::alice::Subgraph"
}
]
},
{
"name":"audio_capture",
"components":[
{
"name":"ml",
"type":"isaac::alice ::MessageLedger"
},
{
"name":"isaac.audio.AudioCapture",
"type":"isaac::audio::AudioCapture"
}
]
},
{
"name":"voice_command_detector",
"components":[
{
" name":"ml",
"type":"isaac::alice::MessageLedger"
},
{
"name":"isaac.audio.VoiceCommandFeatureExtraction" ,
"type":"isaac::audio::VoiceCommandFeatureExtraction"
},
{
" name":"isaac.ml.TensorflowInference",
"type":"isaac::ml::TensorflowInference"
},
{
"name":"isaac. audio.VoiceCommandConstruction",
"type":"isaac::audio::VoiceCommandConstruction"
}
]
}
],
"bords" :[
{
"source":"audio_capture/isaac.audio.AudioCapture/audio_capture",
"target":"voice_command_detector/isaac.audio.VoiceCommandFeatureExtraction/audio_packets"
},
{
"source":"voice_command_detector/isaac.audio.VoiceCommandFeatureExtraction/feature_tensors",
"target":"voice_command_detector/isaac.ml.TensorflowInference/input_tensors"
},
{
"source":"voice_command_detector/isaac.ml.TensorflowInference/output_tensors",
"target":"voice_command_detector/isaac.audio.VoiceCommandConstruction/keyword_probabilities"
},
{
"source":"voice_command_detector/isaac.audio.VoiceCommandConstruction/detected_command",
"target":"subgraph/interface/detected _command"
}
]
},
"config":{
"audio_capture":{
"isaac.audio.AudioCapture":{
"sample_rate":16000,
"num_channels":1,
"audio_frame_in_milliseconds":100,
"ticks_per_frame":5
}
},
"voice_command_detector":{
"isaac.audio.VoiceCommandFeatureExtraction":{
"audio_channel_index":0,
"minimum_time_between_inferences":0.1
},
"isaac.ml.TensorflowInference":{
"model_file_path":"apps/ev3/voice_control/model/isaac_vcd_model.pb",
"config_file_path":"apps/ev3/voice_control/model/isaac_vcd_config. pb"
},
"isaac.audio.VoiceCommandConstruction":{
"command_list":[
"jetson",
"jetson left",
"jetson right"
],
"command_ids":[0, 1, 2],
"max_frames_allowed_after_keyword_detected":14
}
}
}
}

Un sous-graphe peut être réutilisé dans de nombreuses applications. En fait, la pile de navigation d'isaac est utilisée comme sous-graphe.

Partie 4 :Exécuter les applications Isaac sur EV3

Le pilote (jetson-ev3/packages/ev3/BUILD) répond aux mêmes commandes que le pilote de base Segway RMP. Cela signifie qu'il fonctionnera avec de nombreuses applications qui fonctionnent sur Kaya ou Carter, ce qui en fait une troisième option et beaucoup moins chère !

J'ai adapté certaines des applications créées pour présenter les robots Carter et Kaya :

Partie 5 :Odométrie

Pour rouler en mode autonome, il est important d'avoir un bon compteur kilométrique. Ceci est utilisé pour estimer la position du robot dans le temps. Ajustons-le à l'aide de l'application ev3 :

[email protected] :~/ml/jetson-ev3$ ./engine/build/deploy.sh --remote_user andrei -p //apps/ev3:ev3 -pkg -d jetpack43 -h 192.168.0.173

[email protected]:~$ brickrun ./ev3_control_server ev3dev.local:9000

[email protected]:~/deploy /andrei/ev3-pkg$ ./apps/ev3/ev3 --graph ./apps/assets/maps/map.graph.json --config ./apps/assets/maps/map.config.json

Nous devons estimer deux choses :

Les formules pour les vitesses linéaires et angulaires sont :

Trouver la vitesse angulaire est facile :c'est la différence des moteurs droit et gauche divisée par la longueur de la base.

Trouver la vitesse linéaire est un peu plus complexe. Nous avons 3 cas :

Test de vitesse angulaire :

Nous utiliserons la commande manuelle pour faire pivoter le robot à 360 degrés en place. Cela se fait en déplaçant les moteurs gauche et droit à des vitesses opposées. Connaissant les vitesses des deux moteurs, nous pouvons calculer la vitesse angulaire.

Essayons :

Expérience sur les vitesses angulaire et linéaire :

Je vais conduire le char et à la fin essayer de le ramener à l'emplacement de départ. Les données d'odométrie doivent être aussi proches que possible de 0 à la fin si nous calculons correctement les vitesses.

Partie 6 :Tout rassembler

Ok, donc nous sommes allés si loin juste pour avoir un char RC coûteux ? Non, nous pouvons maintenant utiliser toutes les différentes parties d'Isaac. Émettre des commandes vocales par exemple et faire se déplacer le robot de manière autonome. Vérifiez le voice_control pour un exemple.

Il utilise les joyaux audio et d'apprentissage automatique d'Isaac. Qu'est-ce qu'une gemme ? Comme indiqué dans le manuel :« GEMs :une collection d'algorithmes robotiques de la planification à la perception, la plupart accélérés par GPU. »

J'ai formé mon propre RNN en suivant les étapes expliquées dans ce tutoriel. Assurez-vous simplement d'avoir beaucoup de données, en particulier pour le cas des mots-clés inconnus/silence/bruit aléatoire.

J'ai entraîné le mien à reconnaître 3 mots :« jetson », « gauche » et « droite ». Vous pouvez trouver le modèle enregistré ici. Avec ces 3 mots on peut composer 2 commandes :"jetson left" et "jetson right".

La partie détection est décrite ici, dans son propre sous-graphe, prêt à être utilisé et réutilisé.

Fondamentalement, ce qu'il fait est d'écouter le microphone et si l'une des commandes est captée, il produira un voice_command_id. Il utilise le RNN précédemment formé pour cela.

Nous pouvons prendre cette commande_détectée et la transmettre à notre propre codelet :

{
"source":"voice_detection.subgraph/interface/detected_command",
"target":"voice_control_components/goal_generator/detected_command"
}

à partir du codelet, nous pouvons générer un objectif et le publier :

auto proto =rx_detected_command().getProto();
int id =proto.getCommandId();
auto goal_proto =tx_goal(). initProto();
goal_proto.setStopRobot(true);
goal_proto.setTolerance(0.1);
goal_proto.setGoalFrame("robot");
ToProto(Pose2d::Rotation( 90), goal_proto.initGoal());
tx_goal().publish();

Cela fixe un objectif pour faire pivoter le robot vers la gauche avec 90 degrés. Nous pouvons définir différents objectifs dans différents cadres. Cela aurait pu être d'aller à une coordonnée dans le cadre "monde", comme les coordonnées de la cuisine. Il aurait pu définir une Pose2::Translate(1.0, 0) dans le cadre du robot pour faire avancer le robot de 1 mètre.

Et à partir de là, nous passons l'objectif au planificateur global.

{
"source":"voice_control_components/goal_generator/goal",
"target":"navigation.subgraph/interface/goal"
}

Où toute la magie opère :

Malheureusement il ne fonctionnera qu'en mode 10 W, pas 5 W, ce qui est un peu trop pour ma batterie. En mode 5W, l'inférence prend trop de temps :

J'ai essayé avec des RNN plus petits et en passant de 2 cœurs de processeur disponibles (nvpmodel -m 1) à 3, mais cela n'a pas beaucoup aidé. Il a réduit le temps à 30 ms pour l'inférence, encore trop long pour des résultats précis.

Partie 7 :Cartographie

Pour créer une carte, nous devons exécuter une instance d'Isaac sur Jetson et une sur l'ordinateur hôte. La cartographie demande beaucoup de ressources, plus que Jetson Nano ne peut en gérer.

[email protected] :~/ml/jetson-ev3$ ./engine/build/deploy.sh --remote_user andrei -p //apps/ev3:gmapping_distributed_ev3 -pkg -d jetpack43 -h 192.168.0.218

[email protected]:~/deploy/andrei/gmapping_distributed_ev3-pkg$ ./apps/ev3/gmapping_distributed_ev3

[email protected]:~/ml/jetson-ev3$ bazel run apps/ev3:gmapping_distributed_host

N'oubliez pas de modifier le fichier apps/ev3/gmapping_distributed_host.app.json avec votre IP Jetson :

"tcp_subscriber":{
"isaac.alice.TcpSubscriber":{
"port":5000,
"host" :"192.168.0.218"
}
}

Source :Réservoir autonome


Processus de fabrication

  1. Autonomous Driving AI for Donkey Car Garbage Collector
  2. Tank Day 23 :Portée et relèvement
  3. Robot autonome quadrupède JQR
  4. Préparer un avenir autonome
  5. Modèle de char de combat usiné CNC
  6. Un robot autonome ouvre des portes
  7. Les assembleurs autonomes assemblent
  8. Qu'est-ce qu'un char de réserve ?
  9. Conseils de sécurité pour le soudage des réservoirs de carburant