Didacticiel de commande et de contrôle
Introduction
Command and Control est un nouveau modèle LabVIEW ajouté pour la saison 2016 qui organise le code robot en commandes et contrôleurs pour une collection de sous-systèmes spécifiques aux robots. Chaque sous-système dispose d’une boucle de contrôle indépendante ou d’une machine à état fonctionnant au taux approprié pour le mécanisme et les commandes de haut niveau qui mettent à jour les opérations souhaitées et définissent les points de consigne. Il est ainsi très facile dans le code autonome de construire des séquences synchrones de commandes. Pendant ce temps, TeleOp en tire profit, car il peut utiliser les mêmes commandes sans avoir besoin d’attendre la terminaison, permettant l’annulation facile et l’initiation de nouvelles commandes en fonction des entrées émanant de l’équipe de pilotage. Chaque sous-système dispose d’un panneau affichant ses valeurs de capteurs et de contrôle en fonction du temps, et de traçage des commandes pour faciliter le débogage.
Qu’entend-t-on par commande et contrôle?
Command and Control reconnaît que les robots FRC® ont tendance à être construits de mécanismes relativement indépendants tels que Drive, Shooter, Arm, etc. Chacun d’eux est appelé sous-système et a besoin de code qui coordonnera les différents capteurs et actionneurs du sous-système afin de compléter les commandes demandées, ou des actions, telles que « Close Gripper » ou « Lower Arm ». L’un des principes clés de ce cadre est que les sous-systèmes auront chacun une boucle de contrôleur indépendante qui est uniquement responsable de la mise à jour des moteurs et autres actionneurs. Le code en dehors du contrôleur de sous-système peut émettre des commandes qui peuvent modifier la sortie du robot, mais ne doivent pas modifier directement les sorties. La différence est très subtile, mais cela signifie que les sorties ne peuvent être mises à jour qu’à partir d’un seul emplacement du projet. Cela accélère le débogage d’un robot se comportant de façon inattendue en vous donnant la possibilité de regarder à travers une liste de commandes envoyées au sous-système plutôt que de rechercher votre projet pour dénicher l’endroit où une sortie peut avoir été modifiée. Il devient également plus facile d’ajouter un capteur supplémentaire, de changer d’engrenage ou de désactiver un mécanisme sans avoir besoin de modifier le code à l’extérieur du contrôleur.
Game code, primarily consisting of Autonomous and TeleOp, will typically need to update set points and react to the state of certain mechanisms. For Autonomous, it is very common to define the robot’s operation as a sequence of operations – drive here, pick that up, carry it there, shoot it, etc. Commands can be wired sequentially with additional logic to quickly build complex routines. For TeleOp, the same commands can execute asynchronously, allowing the robot to always process the latest driver inputs, and if implemented properly, new commands will interrupt, allowing the drive team to quickly respond to field conditions while also taking advantage of automated commands and command sequences.
Pourquoi devrais-je utiliser la commande et le contrôle ?
Command and Control ajoute des fonctionnalités aux modèles de projet LabVIEW existants, permettant au code de mieux évoluer avec des robots et des code plus sophistiqués. Les sous-systèmes sont utilisés pour abstraire les détails de l’implémentation, et le code du jeu est construit à partir de séquences de commande Vi de haut niveau. Les commandes elles-mêmes sont des VIs qui peuvent mettre à jour les points de consigne, effectuer une mise à l’échelle numérique/correspondance entre les unités d’ingénierie et les unités de mécanisme et offrir des options de synchronisation. Si des modifications physiques sont apportées au robot, telles que la modification d’un rapport d’engrenage, des modifications peuvent être apportées à quelques commandes Vis pour refléter cette modification sur l’ensemble du code.
L’encapsulation des I/O permet un fonctionnement plus prévisible et un débogage plus rapide lorsque des conflits de ressources se produisent. Étant donné que chaque commande est un VI, vous pouvez passer une seule étape à travers les commandes ou utiliser la fonctionnalité intégrée Trace pour afficher une liste de toutes les commandes envoyées à chaque sous-système. Le cadre de développement utilise une notification asynchrone et une propagation cohérente des données, ce qui facilite le codage d’une séquence de commandes ou l’ajout d’une logique simple pour déterminer la commande adéquate à exécuter.
Partie 1 : Explorateur de projet
L’Explorateur de projets fournit une organisation pour tous les Vis et les fichiers que vous utiliserez pour votre système robot. Vous trouverez ci-dessous une description des principaux composants de l’Explorateur de projets pour aider à l’expansion de votre système. Les éléments les plus fréquemment utilisés ont été marqués en gras.
- Mon ordinateur
Les éléments qui définissent l’opération sur l’ordinateur sur lequel le projet a été chargé. Pour un projet de robot, il est utilisé comme cible de simulation et est rempli de fichiers de simulation.
- Fichiers de support Sim
The folder containing 3D CAD models and description files for the simulated robot.
- Simulation de robot Readme.html
Documents the PWM channels and robot info you will need in order to write robot code that matches the wiring of the simulated robot.
- Dépendances
Expose les fichiers utilisés par le code du robot simulé; se remplira lorsque vous concevez le code de la cible du robot simulé.
- Build Specifications
Cela contiendra les fichiers qui spécifient comment compiler et déployer du code pour le robot simulé cible .
- Cible (roborio-TEAM-FRC.local)
Les éléments qui définissent l’opération sur le roboRIO situé à (adresse).
- Lecteur
L’implémentation du sous-système et les commandes de la base pilotable du robot. Elle sert une alternative personnalisée aux RobotDrive VIs de la WPILib .
- Environnement de développement
Les Vis utilisés pour le code robot qui ne fait pas partie d’un sous-système et qui ne sont pas très souvent utilisés.
- Begin
Appelé une fois quand le code robot démarre pour la première fois. Ceci est utile pour le code d’initialisation qui n’appartient pas à un sous-système en particulier.
- Disabled
Appelé une fois pour chaque paquet désactivé et peut être utilisé pour déboguer les capteurs lorsque vous ne voulez pas que le robot se déplace.
- Finish
Pendant l’exécution du code du robot, ce VI peut être appelé lorsque le code du robot se termine. Il n’est pas appelé lorsque le programme avorte ou lorsque l’alimentation est coupée.
- Periodic Tasks
Un bon endroit pour les boucles périodiques ad hoc pour le débogage ou la surveillance
- Robot Global Data
Utile pour partager des informations du robot qui n’appartiennent pas à un sous-système en particulier.
- Support Code
Débogage et aides au développement du code.
- Vision
Sous-système et commandes pour la caméra et le traitement d’image.
- Robot Main.vi
C’est le VI que vous lancez pour l’execution du code au complet de votre robot.
- Autonomous.vi
Ce VI est exécuté pendant le mode autonome.
- Teleop.vi
Ce VI est appelé pour chaque paquet du mode TeleOp.
- Test.vi
Ce VI est exécuté lorsque la Driver Station est en mode test.
- SubSystems.vi
Ce VI renferme et démarre tous les sous-système.
- Dépendances
Affiche les fichiers utilisés par le code robot.
- Build Specifications
Utilisé pour compiler et exécuter le code en tant qu’application de démarrage une fois que le code fonctionne correctement.
Explorateur de projets pour le sous-système lecteur
- Commands:
Ce dossier contient les VIs de commandes qui commandent au contrôleur d’effectuer une opération. Il contient également des modèles pour la création de commandes de déplacement supplémentaires.
Note
Après avoir créé une nouvelle commande, vous pouvez avoir besoin de modifier Drive Setpoints.ctl
pour ajouter ou mettre à jour les champs utilisés par le contrôleur pour définir la nouvelle fonctionnalité. Vous pouvez également avoir besoin d’entrer dans le Controller.vi pour le déplacement et modifier la structure case afin d’ajouter un cas pour chaque valeur.
Implémentation
Il s’agit des VIS et des contrôles utilisés pour construire le sous-système.
- Infrastructure VIs
Drive Check for New Command: Il est appelé à chaque itération de la boucle du contrôleur. Il vérifie les nouvelles commandes, met à jour les données de synchronisation et, une fois terminé, notifie une commande en attente.
Drive Command Helper.vi: Les commandes appellent ce VI pour informer le contrôleur qu’une nouvelle commande a été émise.
Drive Controller Initialization.vi: Il alloue le notifiant et combine la synchronisation, la commande par défaut et d’autres informations dans un seul câble de données.
Drive Controller.vi: Ce VI contient la boucle pour le contrôle/la machine à états. Le panneau peut également contenir des affichages utiles pour le débogage.
Drive Operation.ctl: Ce typedef définit les modes opérationnels du contrôleur. De nombreuses commandes peuvent partager une opération.
Drive Setpoint.ctl: Il contient les champs de données utilisés par tous les modes d’opération du sous-système de déplacement.
Drive Published Globals.vi: Une place utile pour publier des informations globales du sous-système de déplacement.
Partie 2 : Initialisation du sous-système de déplacement
Sur le diagramme bloc du contrôleur, il y a des commentaires en fond vert qui soulignent les zones clés qu’il serait judicieux de savoir comment modifier.
La zone située à gauche de la boucle de contrôle s’exécute une fois lorsque le sous-système démarre. C’est là que vous allouez et initialisez généralement toutes les données d’I/O et d’état. Vous pouvez publier les I/O refnums, ou vous pouvez les enregistrer en mode test uniquement pour les garder privés afin que d’autres codes externes ne puissent pas mettre à jour les moteurs sans utiliser une commande.
Note
L’initialisation des ressources pour chaque sous-système dans leur Controller.vi respectif plutôt que dans Begin.vi améliore l’encapsulation des I/O, réduisant les conflits de ressources potentiels et simplifie le débogage.
Une partie de l’initialisation consiste à sélectionner l’opération par défaut et à définir des valeurs de points de consigne lorsqu’aucune autre opération n’est en cours de traitement.
À l’intérieur de la boucle de contrôle se trouve une statement à conditions où les opérations sont effectivement implémentées. Les points de consigne, les délais d’itération, le nombre d’itérations et les capteurs peuvent tous avoir une influence sur la façon de fonctionner du sous-système. Cette structure à condition a une valeur pour chaque état d’opération du sous-système.
Chaque itération de la boucle du contrôleur mettra éventuellement à jour le Trace VI. Le cadre de développement intègre déjà le nom, l’opération et la description du sous-système, et vous trouverez peut-être utile de mettre en forme des valeurs des points de consigne dans les informations de trace. Ouvrez le Trace VI et cliquez sur Enable pendant que le code robot s’exécute pour atteindre les points de consigne actuels et les commandes envoyées à chaque sous-système.
L’objectif principal du contrôleur est de mettre à jour les actionneurs du sous-système. Cela peut se produire dans la structure à conditions, mais très souvent, il est avantageux de le faire en aval de la structure pour s’assurer que les valeurs sont toujours mises à jour avec la valeur correcte et dans un seul emplacement dans le code.
Partie 3 : Commandes intégrées dans le sous-système de déplacement
Il existe 3 commandes d’exemple jointes pour chaque nouveau sous-système :
Drive For Time.vi
Ce VI configure les moteurs de manière à fonctionner pendant un certain nombre de secondes. Il se synchronise éventuellement avec la fin de l’exécution de la commande.
La condition The Drive for Time actionnera les moteurs au point de consigne jusqu’à ce que le délai s’écoule ou qu’une nouvelle commande soit émise. Si les moteurs ont le paramètre safety timeout activé, il est nécessaire de les mettre à jour au moins une fois tous les 100ms. C’est pourquoi le code attend la plus petite fraction du temps restant et 50ms.
Drive Immediate.vi
Obtient les vitesses souhaitées à gauche et à droite pour les moteurs et configurera ces moteurs immédiatement à ces points de consigne.
La condition Immediate met à jour les moteurs au point de consigne défini par la commande. La commande n’est pas considérée comme terminée puisque vous souhaitez que les moteurs conservent cette valeur jusqu’à ce qu’une nouvelle commande entre ou jusqu’à ce qu’un délai d’expiration soit atteint. Le délai d’attente est utile è chaque fois qu’une commande comprend une zone morte. De petites valeurs ne seront pas demandées si elles sont plus petites que la zone morte, et entraîneront un grongnement ou un fluage à moins que la commande ne temporise.
Stop Driving.vi
met les moteurs d’entraînement à zéro, ce qui immobilise le robot.
La commande Reserve éteint les moteurs et attend une nouvelle commande. Lorsqu’elle est utilisée avec une séquence de commande nommée, Reserve identifie que le sous-système de déplacement fait partie de cette séquence, même si elle n’est pas en train de déplacer le robot. Cela permet d’arbitrer la ressource sous-système entre les commandes simultanément en cours d’exécution.
Partie 4 : Création de nouvelles commandes
Le cadre de développement Command and Control permet aux utilisateurs de créer facilement de nouvelles commandes pour un sous-système. Pour créer une nouvelle commande ouvrez le dossier sous-système/Commands dans la fenêtre explorateur de projet, choisissez l’un des VI Templates à utiliser comme point de départ de votre nouvelle commande, cliquez avec le bouton droit et sélectionnez New From Template.
Immediate: Ce VI informe le sous-système d’un nouveau point de consigne.
Immediate with deadband: Ce VI compare la valeur d’entrée de la zone morte et informe éventuellement le sous-système du nouveau point de consigne. Ceci est très utile lorsque des valeurs continues joystick sont utilisées.
With duration: Ce VI informe le sous-système d’exécuter cette commande pendant la durée donnée, puis de revenir à l’état par défaut. La synchronisation détermine si ce VI démarre l’opération et retourne immédiatement ou attend que l’opération se termine. La première option est couramment utilisée pour le mode TeleOp, et la seconde pour des séquences en mode autonome.
Dans cet exemple, nous allons ajouter la nouvelle commande « Drive for Distance ».
Premièrement, enregistrez le nouveau VI avec un nom descriptif tel que « Drive for Distance ». Ensuite, déterminez si la nouvelle commande a besoin d’une nouvelle valeur ajoutée à enum typedef des Drive Operations. Le code de projet initial a déjà une valeur enum de Drive for Distance, mais l’image suivante montre comment vous en ajouteriez une si nécessaire.
Si une commande a besoin d’informations supplémentaires pour les exécuter, ajoutez-les au contrôle des points de consigne. Par défaut, le sous-système de déplacement comporte des champs pour le point de consigne gauche, le point de consigne droit et la durée ainsi que l’opération à exécuter. La commande Drive for Distance peut réutiliser Duration en tant que distance, mais ajoutons un contrôle numérique au Drive Setpoints.ctl appelé Distance (pieds).
Une fois que nous avons tous les champs nécessaires pour spécifier notre commande, nous pouvons modifier Drive for Distance.vi, nouvellement créé. Comme indiqué ci-dessous, sélectionnez Drive for Distance à partir du menu déroulant de l’enum’s et ajouter les paramètres au VI pour spécifier la distance, les vitesses, etc. Si les unités ne correspondent pas, la commande VI est un excellent endroit pour effectuer la correspondance entre les unités.
Ensuite, ajoutez du code au Drive Controller pour définir ce qui se passe lorsque la commande Drive for Distance s’exécute. Cliquez avec le bouton droit sur la Structure de conditions et le dupliquer ou ajouter d’autres cas chaque valeur. Cela créera une nouvelle condition « Drive for Distance ».
Afin d’accéder aux nouveaux champs de setpoint, développez le nœud de dissocation « Access Cmd setpoints ». Ouvrez votre encodeur(s) à l’extérieur, à gauche de la boucle. Dans le nouveau diagramme de la structure case, nous avons ajouté un appel pour réinitialiser l’encodeur sur la première itération de boucle et le lire autrement. Il y a aussi un simple code qui compare les valeurs de l’encodeur et met à jour la puissance du moteur. Si de nouveaux contrôles sont ajoutés au cluster des points de consigne, vous devez également envisager de les ajouter au Trace VI. Les modifications nécessaires sont indiquées dans l’image ci-dessous.
Partie 5 : Création d’un sous-système
Afin de créer un nouveau sous-système, cliquez avec le bouton droit sur la cible roboRIO et sélectionnez New» Subsystem. Dans la boîte de dialogue contextuel, entrez le nom du sous-système, répertoriez les modes d’opération et spécifiez la couleur de l’icône.
Lorsque vous cliquez sur OK, le dossier du sous-système sera généré et ajouté au dossier et à l’arborescence du disque de projet. Il contiendra une implémentation de base des VIS et des contrôles qui constituent un sous-système. Un appel au nouveau contrôle sera inséré dans les sous-systèmes VI. Le contrôle VI s’ouvrira, prêt pour que vous ajoutiez des E/S et à implémenter une machine d’état ou un code de contrôle. Les icônes VI générées utilisent la couleur et le nom fournis dans la boîte de dialogue. Le code généré utilise des typedefs pour définir des champs et des points de consigne et des opérations.
Vous trouverez ci-dessous le diagramme bloc du sous-système nouvellement créé. Ce code est généré automatiquement lorsque vous créez le sous-système.