Tutorial KinematicController/fr

Introduction
Ce tutoriel décrit comment générer un contrôleur cinématique simple à utiliser avec les assemblages créés avec l'atelier Assembly3 à partir de quelques lignes de code Python.

N'importe quel éditeur de texte peut être utilisé pour coder. Mon choix se porte sur Atom, mais l'éditeur intégré de FreeCAD fonctionne bien aussi.

Les exemples de code suivants peuvent être copiés et collés dans un fichier texte vide, puis enregistrés sous le nom de votre choix comme fichier ou.

Structure de base
La structure de base consiste en une fonction et un commutateur pour vérifier si la macro est utilisée comme un conteneur pour les classes, les méthodes, etc. ou si elle est exécutée seule. Seule la deuxième option lancera la fonction. Cette fonction est vide pour le moment.

Trouver les contraintes pilotes
Les contraintes pilotes sont des objets dans un document FreeCAD. Elles doivent être marquées pour pouvoir être trouvées.

Pour ce contrôleur, le suffixe doit être attaché au label d'une contrainte pilote. Il peut être séparé par un ou  pour plus de clarté, car nous ne vérifierons que si le label se termine par.

Une fonction qui reçoit un objet document et renvoie une liste de contraintes pilotes (les noms dans ce cas) fera l'affaire.

La fonction charge le document actif dans la variable, puis appelle la fonction  et lui transmet le contenu de. La liste retournée est chargée dans qui est ensuite vérifiée pour contenir au moins un élément. Si c'est le cas, la liste est finalement imprimée dans la Vue rapport.

La macro jusqu'à présent...

Panneau de contrôle
Le panneau de contrôle est construit à partir de widgets Qt, une fenêtre principale contenant plusieurs widgets d'entrée/sortie.

Chaque widget doit être importé avant de pouvoir être utilisé, mais ils peuvent être importés en un seul ensemble. La ligne d'importation est placée en haut du fichier.

Fenêtre principale
Pour la fenêtre principale, la ligne d'importation ressemble à ceci :

La fenêtre principale appelée est un objet de classe instancié à partir du widget.

Elle possède deux méthodes init. initialise le nouvel objet de la classe, gère les arguments entrants et lance qui gère tous les widgets de la fenêtre principale.

Pour lancer un seul panneau de commande, une instance, appelée, de cette classe sera créée avec (l'objet document) et  (le premier de la liste des contraintes de conduite) transférés à cette instance. Enfin, la méthode de la classe ouvre la fenêtre de dialogue.

Pour gérer plus d'un contrôleur (driver), nous devons vérifier la liste des contrôleurs et créer une instance pour chaque élément de la liste et transférer l'élément en cours.

Ces lignes remplacent la commande dans la branche else de la fonction.

Remarque : La collecte d'une nous permet de lancer tous les panneaux en même temps. (Je ne peux pas encore expliquer ce comportement...)

L'exécution de la macro affichera une fenêtre de dialogue vide et propre, en attente de widgets :



La macro jusqu'à présent...

Paramètres de réglage
Il est maintenant temps de remplir la méthode :

représente la contrainte pilote et stocke un mot clé pour son type. Ce dernier est utilisé pour choisir la propriété correcte avec chaque contrainte.

Méthode getDriverType
Pour une utilisation future, nous avons besoin du type de pilote (Angle, Distance, Longueur) et donc une méthode doit être définie :

Cette méthode vérifie si le type de la contrainte donnée peut être trouvé dans l'une des listes, et renvoie le type de dimension qui doit être contrôlé.

On suppose que dans le document cinématique, le pilote est marqué correctement et fonctionne s'il était édité manuellement. Dans ce cas, il n'est pas nécessaire de filtrer les contraintes géométriques telles que Colinear ou PointsCoincidence (mais ce serait l'endroit pour le faire...).

Propriétés de la fenêtre
La taille de la fenêtre est définie par ses dimensions minimale et maximale. En utilisant les mêmes valeurs, on obtient une taille fixe.

Le titre indique le nom du pilote et précise s'il s'agit d'un angle, d'une distance ou d'une longueur. Enfin, on demande à la fenêtre de rester au dessus de toutes les fenêtres.

Paramètres de réglage supplémentaires
L'étape suivante consiste à extraire la valeur actuelle du pilote et à définir les valeurs de début et de fin par défaut en fonction du type de pilote.

Une distance ne peut pas être négative et exactement nulle, ce qui rend le solveur perplexe. La valeur de départ est donc fixée à 0,001. Les angles acceptent des valeurs négatives et obtiennent des valeurs symétriques. (Si les longueurs acceptent des valeurs négatives reste à prouver finalement...)

Le suffixe de l'unité doit être conservé pour renvoyer la valeur à la propriété de la contrainte à la fin. Les distances et les longueurs nécessitent des valeurs avec des unités.

Le traitement des unités et l'affichage des valeurs sous forme de chaînes de caractères dans plusieurs widgets nécessitent de convertir assez souvent les chiffres en chaînes de caractères et inversement.

Pour compléter les paramètres, nous définissons un nombre de pas par défaut qui doivent être calculés lorsque le mouvement est automatisé et si le commutateur est réglé sur, une photo sera prise à chaque pas du mouvement.

Intitulés
Maintenant, trois intitulés sont ajoutés pour afficher le début, la fin et la valeur en cours.

Tout d'abord, la classe doit être importée, c'est-à-dire que la liste d'importation doit être étendue comme ceci :

Dans la méthode, nous insérons :

Le placement est fait avec la méthode héritée. Dans ce cas, la description d'un rectangle est utilisée (position X, position Y, largeur, hauteur).

Les première et troisième lignes pourraient être combinées, mais cela n'est pas recommandé pour des raisons de clarté :

L'exécution de la macro avec un document d'assemblage cinématique créerait une fenêtre de dialogue comme celle-ci :



La macro jusqu'à présent...

Curseur
Pour changer la valeur courante à n'importe quel nombre entre la valeur de début et la valeur de fin, un widget de curseur conviendrait.

Tout d'abord, la classe doit être importée, c'est-à-dire que la liste d'importation doit être étendue comme ceci :

De retour dans la méthode et juste après la section des intitulés (labels), nous insérons :

Le bouton du curseur est placé avec la méthode. Sa valeur doit être calculée à partir de la valeur actuelle et d'un rapport de progression. Le rapport doit être calculé à chaque fois qu'une valeur de début ou de fin est modifiée. Nous insérons donc une autre méthode après la méthode.

Travailler avec un ratio au lieu de modifier les valeurs min et max du curseur présente l'avantage d'une résolution plus fine pour les petites valeurs.

Et après celle-ci, vient une autre méthode définissant ce qu'il faut faire lorsque la position du curseur ou la valeur du curseur change. La méthode est appelée par la méthode  qui fournit également la valeur du curseur comme argument.

Il recalcule la valeur courante à partir de la position du curseur, réécrit le texte de l'intitulé et modifie la propriété de la contrainte en fonction du type de curseur.

L'exécution de la commande lance le solveur pour réorganiser les pièces de l'assemblage avec la valeur modifiée.

La fenêtre de dialogue avec le curseur doit ressembler à ceci et est prête à contrôler un mouvement :



Nous pouvons lancer une fenêtre de dialogue pour n'importe quel document ouvert, elles n'interféreront pas entre elles.

Champs de saisie de texte
Pour définir les valeurs de début et de fin, nous utilisons un widget d'édition de ligne.

Tout d'abord, la classe doit être importée, c'est-à-dire que la liste d'importation doit être étendue comme ceci :

De retour dans la méthode et entre les intitulés (labels) et les sections du curseur, nous insérons :

Les champs de saisie affichent les valeurs de début et de fin par défaut. Ils ne sont pas complets tant que nous n'avons pas ajouté les méthodes permettant de traiter les entrées modifiées. Ceci sera fait par les méthodes et  qui sont insérées entre les méthodes  et.

Les deux convertissent la valeur de la chaîne reçue en un nombre à virgule flottante et modifient soit soit  et l'intitulé correspondant en conséquence. Ensuite, la valeur du curseur est mise à jour.

La fenêtre de dialogue avec les champs de saisie de texte doit ressembler à ceci et est prête à modifier la portée d'un mouvement :

.

La macro jusqu'à présent...

Mouvement
Pour mettre l'assemblage en mouvement, nous avons besoin :
 * Des boutons pour déclencher le mouvement dans la direction souhaitée.
 * Un champ de saisie pour modifier le nombre de pas pour des mouvements plus rapides ou plus doux.
 * Une case à cocher pour indiquer si nous voulons prendre une séquence d'images.

Boutons avant et arrière
Pour déplacer automatiquement les pièces de l'assemblage, nous avons besoin de deux boutons pour déclencher les mouvements, un vers la position de départ et un vers la position d'arrivée. Ces deux boutons et un bouton de fermeture utiliseront un widget.

Les petits assemblages calculent un peu trop vite et montrent des sauts au lieu d'un mouvement régulier. Pour le ralentir, nous utilisons la méthode du module  qui doit être importé en premier.

Another import and another widget:

Dans la méthode, nous insérons les boutons après la section du curseur :

Les méthodes traitant des boutons enfoncés sont, , et. Ils sont insérés après la méthode.

La méthode fait appel à la méthode héritée  qui ferme simplement la fenêtre de dialogue et clôt ainsi la macro.

Les deux et  comptent les pas qu'il reste à faire pour atteindre la position voulue et calculent la longueur d'un pas en fonction du nombre de pas. Pour l'instant, nous utilisons le nombre par défaut de 10 pas.

Chaque tour de la boucle while augmente/diminue la valeur en cours et met à jour les valeurs du curseur qui déclenche en arrière-plan (voir Paragraphe curseur). Après une pause pour laisser l'ordinateur fournir une autre vue 3D actualisée, le décompte des étapes restantes termine la boucle.

S'il n'y a plus de pas, le curseur est placé sur la première/dernière position du curseur, juste au cas où une erreur d'arrondi se serait produite.

La fenêtre de dialogue avec les boutons doit ressembler à ceci et vous pouvez maintenant déplacer l'assemblage de 10 pas vers la position de début/fin souhaitée :



La macro jusqu'à présent...

Nombre d'étapes
Le paramètre par défaut est d'obtenir une impression rapide si l'assemblage se déroule comme prévu sans perdre trop de temps de calcul.

Si les pièces sautent au lieu de se déplacer en douceur, ou si les pilotes basés sur les angles ont tendance à poser des problèmes lorsque la différence entre deux angles est trop importante, ces deux problèmes peuvent être résolus en augmentant le nombre d'étapes.

Un autre widget d'édition de ligne est donc utilisé pour modifier le nombre d'étapes (placé après les widgets d'édition de ligne existants) :

La méthode connexe remplit simplement le paramètre  avec la valeur saisie. Elle est insérée après la méthode.

La fenêtre de dialogue permettant de modifier le nombre d'étapes doit ressembler à ceci :



Séquence d'images
Lorsque le mouvement de notre assemblage répond à nos attentes, nous pouvons prendre une photo de chaque étape. La séquence d'images qui en résulte peut être utilisée pour créer une courte animation gif.

Pour mettre en œuvre cette fonctionnalité, nous avons besoin d'un widget, et d'un répertoire pour stocker les images.

Une importation et un widget de plus :

Dans la méthode, nous insérons la case à cocher après la section du curseur :

La méthode synchronise le paramètre  et l'affichage de la coche.

Pour définir les paramètres de sortie, nous utilisons la méthode :

Tout d'abord, le chemin de l'image doit être adapté à votre système d'exploitation ; la dernière partie est le nom de l'image sans le numéro du moment et la balise du fichier. Ceci doit être fait manuellement pour le moment.

Ensuite, suivent la balise du fichier pour terminer le nom de l'image, la hauteur et la largeur de l'image, et la façon dont le fond doit être rempli ( (fond de la vue 3D),, , ou ).

Pour avoir toujours un nombre à 3 chiffres, des zéros de tête doivent être préfixés au paramètre du compteur.

Finally the scripted version of the command Std ViewScreenShot is used to take a picture based on the mentioned parameters.

Still no pictures taken!?! No problem, as this method doesn't get called yet, and so we need to insert a call in the while loop of and. Right after we insert this line:

Now the macro should be ready to control an assembly and to take pictures for an animated gif.

The final version of the dialog window:



And finally the whole macro

Don't forget to set the path in the output method!

Some imperfections

 * The order of the image sequence is reversed as we use the variable steps_left which is counted down.
 * The image directory and the image name are hard-coded.
 * Multiple Controllers are not synchronised.