Combiner routage manuel et routage automatique dans Eagle; ripup sélectif dans un Eagle ULP

8

Dans Eagle, je préfère souvent acheminer moi-même certains câbles (alimentation, xtal, UBS, etc.) et laisser le reste à l'autorouteur. Lorsque je ne suis pas satisfait du résultat, j'achemine un peu plus moi-même et je laisse l'autorouter essayer à nouveau.

Mon problème est d'annuler le travail de l'autorouteur, sans annuler mon propre travail. Pour ce faire, la méthode de base consiste simplement à ne pas enregistrer la version autoroutée, puis à charger à nouveau la carte. Mais une fois que j'ai fait l'erreur de sauvegarder la version autoroutée (et de purger les sauvegardes), je veux toujours pouvoir revenir à la version préautorisée.

Une tentative pour ce faire consiste à identifier tous les fils routés automatiquement dans un ULP et à créer la chaîne de commande pour RIPUP ces segments. Je peux faire en sorte que l'ULP identifie les fils routés automatiquement, par exemple en leur donnant une largeur différente. Mais la commande RIPUP semble extraire le segment de fil sélectionné ET LES SEGMENTS ADJACENTS. Jusqu'à présent, je n'ai pas trouvé de commande qui déchire uniquement le segment de fil sélectionné.

Je suppose donc que j'ai deux questions: - Comment combinez-vous le routage manuel et le routage automatique de manière itérative (essai et erreur)? - Existe-t-il un moyen (probablement à l'aide d'ULP et de commandes) d'extraire un sous-ensemble de segments de fil?

(mise à jour) J'ai essayé l'approche inverse: dans un ULP, rassemblez tous les segments de fil que je veux conserver, faites une extraction complète, puis restaurez les segments de fil (à l'aide de la commande ROUTE). Pas de succès, les segments doivent être dans un ordre spécifique pour les commandes de route (pas l'ordre dans lequel l'ULP les trouve :(), les via doivent être faits en premier, et quelques autres problèmes.

GRRRR, il doit y avoir un moyen facile de le faire, ou suis-je trop optimiste?

Wouter van Ooijen
la source
Si le fichier de données d'Eagle suit la même approche que les anciens avec lesquels j'ai joué (par exemple, ye olde DOS Autotrax), alors chaque segment de piste a une ligne à lui-même. Si les largeurs de piste sont uniques, il devrait être [tm] facile d'identifier les segments de piste et de supprimer les lignes concernées. La faible mémoire me dit qu'à un moment donné, j'ai écrit une routine pour identifier les étiquettes des composants et les redimensionner, les faire pivoter et les déplacer par rapport au corps du composant. L'identification des pistes semble facile à comparer. Enregistrez une copie avant d'exécuter le programme !!! :-).
Russell McMahon
c'est une question formidable, puis-je vous suggérer de la poster également à l'expert Element14 sur Eagle element14.com/community/message/5177 . Si vous le faites et que vous trouvez quelque chose, merci de poster ici!
vicatcu
OK fait. Si cela échoue, je peux essayer les forums eagle.
Wouter van Ooijen

Réponses:

4

Je déteste répondre à ma propre question, mais c'est parti. J'espère que je ne reçois pas de points pour répondre, ce serait bizarre, seulement pour accepter une réponse? (BTW, je n'ai reçu aucune réponse sur le forum Element14.)

La solution consiste à utiliser la commande DRAW, pas ROUTE. DRAW placera un segment de fil, exactement là où vous le spécifiez (contrairement à ROUTE, qui essaie de se connecter à un fil aérien non acheminé. ROUTE est essentiellement inutile dans un script.). Le problème suivant est celui des via: je ne peux pas (ou je ne veux pas) faire la distinction entre un via manuel et un via autorouté, donc je garde tous les via qui connectent deux (ou plus) segments de fil manuels. Les autres via sont supprimés.

Alors, mon script final fait:

prepare a ripup command
for all copper segments that are not 0.01 wide (the width I use for autorouting)
   check both endpoints for a via at that location
      prepare the via to be resurrected when it is visited the 2nd time
   prepare a command that resurrects the copper segment
execute the prepared commands

Notez qu'il ne fonctionnera probablement pas pour plus de deux couches, ni pour autre chose que des segments de fil au niveau de la couche de cuivre.

À mon humble avis, tout le concept des langages ULP et de commande eagle est gênant. Un ULP s'exécute dans un environnement en lecture seule, la seule façon dont il peut affecter le circuit, la carte ou la bibliothèque est de créer une liste de commandes. Cela élimine certaines techniques de programmation utiles, mais le pire est que les commandes n'ont pas été conçues pour être facilement créées à partir d'un ULP. Vous avez besoin de toutes sortes de transformations (dans ce cas: coordonnées, noms de forme) pour traduire du monde ULP au monde CMD.

(modifier) ​​Avant d'exécuter cet ULP, définissez la sélection `` Wire Bend '' pour permettre des angles arbitraires, sinon Eagle tentera d'adapter les fils ressuscités aux angles autorisés, ce qui peut entraîner un désordre sanglant. À mon humble avis, c'est un autre exemple du problème avec ULP / SCR.

Voici le code ULP:

// gather the commands that must be run on exit
string RunOnExit = "";
void cmd( string s ) { RunOnExit += s + "\n"; }

// return an x or y position in the form that can be used in a command
real f( int x ){
   board( B ) switch( B.grid.unit ) {
      case 0: return u2mic(x);
      case 1: return u2mm(x);
      case 2: return u2mil(x);
      case 3: return u2inch(x);
   }
}   

// return the string form of the a via's shape
string sn( int x ){
   if( x == VIA_SHAPE_SQUARE )  return "square";
   if( x == VIA_SHAPE_ROUND )   return "round";
   if( x == VIA_SHAPE_OCTAGON   ) return "octagon";
   if( x == VIA_SHAPE_ANNULUS   ) return "annulus";
   if( x == VIA_SHAPE_THERMAL   ) return "thermal";
   return "unknown-via-shape";
}

// count the number of times x occurs in s
int n_ocurrences( string s, string x ){
   int i, n = 0;
   while( 1 ){
      i = strstr( s, x );
      if( i == -1 ) return n;
      s = strsub( s, i + strlen( x ));
      n++;
   }
}

// add a via, but only when it is visited the second time
string via_list = "";
void add_via( int a, int b ){

   // for all via's
   board( B ) B.signals( S ) S.vias( V ){

      // if the via is at the current location
      if(( V.x == a ) && ( V.y == b )){
         string s, coo;

         // the coordinates of the via are used as its identification
         sprintf( coo, "(%.6f %.6f)", f( V.x ), f( V.y ));         

         // if this is the second visit to this via
         via_list += coo;
         if( n_ocurrences( via_list, coo ) == 2 ){

            // resurrect this via
            sprintf( s, "VIA '%s' %f %s %s;", 
            S.name, f( V.drill ), sn( V.shape[ 1 ] ), coo );
            cmd( s );      
         }
      }
   }         
}

if( !board ){
   dlgMessageBox("start this ULP in Board", "OK");
   exit( 0 );
}

board( B ){ 

   // first delete all coper segments, 
   // later we will resurrect what we want to keep 
   cmd( "RIPUP;" );

   // for all wire segments in the top and bottom copper layers
   B.signals(S) S.wires(W) {
      if( ( W.layer == 1 ) || ( W.layer == 16 ) ){ 

         // that are not 0.01 width (that is what the autorouter uses)
         if( f( W.width ) != 0.01 ){
            string s;

            // resurrect via's adjacent to this wire segment
            add_via( W.x1, W.y1 );
            add_via( W.x2, W.y2 );

            sprintf( s, "CHANGE LAYER %d;", W.layer );
            cmd( s );      

            // resurrect this wire segment                 
            sprintf( 
               s, "WIRE '%s' %f (%.6f %.6f) (%.6f %.6f);", 
               S.name, f( W.width),
               f(W.x1), f(W.y1), f(W.x2), f(W.y2));
            cmd( s );   
         }   
      }
   }
   // dlgMessageBox( RunOnExit, "OK");
   exit( RunOnExit );
}
Wouter van Ooijen
la source
Le ULP / SCR d'Eagle est l'une de ses fonctionnalités les plus puissantes. Comme vous l'avez trouvé, les ULP sont utilisés pour interroger le tableau et écrire des scripts qui peuvent être absolument tout ce que vous pouvez faire vous-même. Voilà son pouvoir. Cela dit, je souhaite que ce soit dans un langage `` normal '', peut-être Python ou même Lua, mais même vous devez admettre que pouvoir faire quelque chose auquel les auteurs du logiciel n'ont pas pensé est un bon sentiment.
akohlsmith
Bien sûr, mais leur puissance doit être exercée de manière arcanique: les ULP sont puissants, mais ne peuvent pas changer le schéma / bord, le SCR est une variante paralysée de l'interface graphique. Ensemble, ils peuvent faire un travail utile, mais les choses auraient pu être beaucoup plus faciles! Et pour mon problème particulier, cela aurait été bien si les choses ajoutées par l'autorouteur étaient identifiables.
Wouter van Ooijen
2
Dans EAGLE v6.3, la commande est WIRE not DRAW (il n'y a pas de commande DRAW).
2

Wouter. Je n'ai pas vu votre question plus tôt car j'étais au Masters la semaine dernière.

La façon dont je traite cela est d'enregistrer une copie de la carte sous un nom différent juste avant d'exécuter le routeur automatique. Je le nomme toujours SAVE.BRD, qui peut être supprimé en toute sécurité une fois terminé.

Mon flux de travail de routage ressemble beaucoup au vôtre. J'achemine les parties critiques manuellement, je m'assure que les classes net sont configurées de manière raisonnable, puis je lance l'autorouteur. Ensuite, je recherche des problèmes comme celui où l’autorouteur n’a pas pu trouver de solution, il a fini par faire quelque chose de gênant, etc. en difficulté, puis réessayez. Cela peut être répété 5 à 10 fois, selon la complexité de la carte. Les premiers passages d'autoroute visent principalement à voir s'il existe une solution et à trouver les points sensibles. Pour cela, je n'utilise même pas de passes d'optimisation. Les autoroutes ultérieures sont avec une optimisation complète, ce qui pour moi est généralement de 8 passes avec des coûts changeant sur ces passes pour obtenir les caractéristiques que je veux.

Même si je fais une sauvegarde dans SAVE.BRD avant chaque passage d'autoroute (puis que je rouvre le fichier d'origine pour continuer), j'essaie de ne pas faire de sauvegarde sur le résultat de routage automatique jusqu'à ce que je sois satisfait de tout. L'enregistrement de l'instantané dans SAVE.BRD à chaque fois est une sauvegarde de sécurité au cas où mes doigts feraient accidentellement une sauvegarde avant d'y penser.

Ce serait bien si Eagle avait une option de ripup pour le dernier passage d'autoroute, mais il n'y a rien de tel.

Olin Lathrop
la source
Votre discipline fonctionnera pour une personne qui est toujours disciplinée. Vous pourriez deviner que je ne le suis pas. Une fois que j'ai effectué un autoroutage, j'ai ensuite apporté des modifications au circuit, puis supprimé le brd et essayé de revenir à la version pré-autoroutée. Pas une bonne idée ... Alors maintenant, j'ai plus ou moins un moyen de désautoroute, à condition que je puisse distinguer les traces autoroutées par la largeur. Ce serait bien si les traces autoroutées avaient un attribut qui les identifiait comme telles.
Wouter van Ooijen
Étrange, j'avais écrit "Salut, Wouter" au début de mon post, mais la partie "Salut" semble avoir été supprimée.
Olin Lathrop
Je crois que c'est une "fonctionnalité" que l'échange de pile a. Ils pensent que dire "Salut" au début d'un message n'est pas nécessaire et devrait être supprimé pour garder les choses "propres". Similaire à leur suppression de @username dans certains cas ... et tout comme dans ce cas où je ne pouvais pas taper @ Olin (sans espace) et @ username dans le même commentaire.
Kellenjb
1

Si le fichier de données d'Eagle suit la même approche que les anciens avec lesquels j'ai joué (par exemple, ye olde DOS Autotrax), alors chaque segment de piste a une ligne à lui-même. Les lignes sont "autonomes" et peuvent être modifiées ou supprimées sans impact sur quoi que ce soit d'autre. Les systèmes «meilleurs» plus récents peuvent ne pas avoir une simplicité aussi puissante.

Si les pistes sont indépendantes, comme ci-dessus, et si les largeurs de piste sont uniques, il devrait [tm] être facile d'identifier les segments de piste et de supprimer les lignes concernées.

La faible mémoire me dit qu'à un moment donné, j'ai écrit une routine pour identifier les étiquettes des composants et les redimensionner, les faire pivoter et les déplacer par rapport au corps du composant. L'identification des pistes semble facile à comparer. Enregistrez une copie avant d'exécuter le programme !!! :-).

Russell McMahon
la source
De quel format de fichier parlez-vous? Le fichier .brd eagle n'est pas un fichier texte. Mon problème avec les segments de piste n'est pas que je ne peux pas les identifier, mais que la seule commande que je sache que je peux utiliser en fera trop: RIPUP déchire non seulement le segment mais (certains) segments adjacents aussi.
Wouter van Ooijen
@Wouter van Ouijen - YMMV :-). Ne pas être un texte en soi ne signifie pas qu'il ne peut pas être piraté - mais il peut le faire. Je ne sais pas à quoi ressemble le fichier Eagle .brd à l'intérieur et je ne sais pas si vous pouvez arracher des segments de piste entiers et concaténer le reste en toute sécurité - probablement pas. Ça vaut le coup d'oeil. Vous pourrez peut-être écrire un lecteur et un réécriveur de fichiers qui reconstruit intelligemment le fichier sans les parties indésirables. Cela dépend de la façon dont le format de fichier est bien connu ou connaissable.
Russell McMahon,
Je me rends compte qu'au moment d'écrire la question, c'était vrai, mais les formats de fichiers d'Eagle sont maintenant des fichiers texte XML simples.
akohlsmith