Kombinieren von Hand-Routing und Auto-Routing in Eagle; selektives Aufreißen in einem Eagle ULP

In Eagle ziehe ich es oft vor, einige Kabel selbst zu verlegen (Strom, xtal, UBS usw.) und den Rest dem Autorouter zu überlassen. Wenn ich mit dem Ergebnis nicht zufrieden bin, route ich selbst weiter und überlasse dem Autorouter einen weiteren Versuch.

Mein Problem besteht darin, die Arbeit des Autorouters rückgängig zu machen, ohne meine eigene Arbeit rückgängig zu machen. Der grundlegende Weg, dies zu tun, besteht einfach darin, die Autorouter-Version nicht zu speichern und das Board dann erneut zu laden. Aber sobald ich den Fehler mache, die autorouted-Version zu speichern (und die Backups zu löschen), möchte ich immer noch in der Lage sein, zur vorautorouted-Version zurückzukehren.

Ein Versuch, dies zu tun, besteht darin, alle automatisch gerouteten Drähte in einem ULP zu identifizieren und die Befehlszeichenfolge zum RIPUP dieser Segmente zu erstellen. Ich kann dafür sorgen, dass das ULP die automatisch gerouteten Drähte erkennt, indem ich ihnen zum Beispiel eine andere Breite gebe. Aber der RIPUP-Befehl scheint das ausgewählte Drahtsegment UND ANGRENZENDE SEGMENTE zu zerreißen. Bisher habe ich keinen Befehl gefunden, der nur das ausgewählte Drahtsegment zerreißt.

Ich denke, ich habe zwei Fragen: - Wie kombinieren Sie Hand-Routing und Auto-Routing auf iterative Weise (Trial-and-Error)? - Gibt es eine Möglichkeit (wahrscheinlich mit ULP und Befehlen), eine Teilmenge von Drahtsegmenten zu zerreißen?

(Update) Ich habe den umgekehrten Ansatz versucht: Sammeln Sie in einem ULP alle Drahtsegmente, die ich behalten möchte, führen Sie einen vollständigen Ripup durch und stellen Sie dann die Drahtsegmente wieder her (mithilfe des ROUTE-Befehls). Kein Erfolg, die Segmente müssen für die Route-Befehle in einer bestimmten Reihenfolge sein (nicht in der Reihenfolge, in der das ULP sie findet :( ), die Vias müssen zuerst gemacht werden und einige weitere Probleme.

GRRRR, es muss einen einfachen Weg geben, oder bin ich zu optimistisch?

Wenn die Datendatei von Eagle dem gleichen Ansatz folgt wie ältere, mit denen ich gespielt habe (z. B. Ihr altes DOS Autotrax), dann hat jedes Tracksegment eine Zeile für sich. Wenn die Spurbreiten eindeutig sind, sollte es einfach sein [tm], Spursegmente zu identifizieren und die betroffenen Linien zu löschen. Schwache Erinnerung sagt mir, dass ich einmal eine Routine geschrieben habe, um Komponentenetiketten zu identifizieren und sie in der Größe zu ändern, zu drehen und relativ zum Komponentenkörper zu verschieben. Track-Identifikation klingt im Vergleich einfach. Speichern Sie eine Kopie, bevor Sie das Programm ausführen !!! :-).
Dies ist eine großartige Frage. Ich schlage vor, dass Sie sie auch an den Element14-Experten auf Eagle element14.com/community/message/5177 senden . Wenn Sie dies tun und etwas finden, posten Sie bitte hier zurück!
OK, fertig. Wenn das fehlschlägt, kann ich es in den Eagle-Foren versuchen.

Antworten (3)

Ich hasse es, meine eigene Frage zu beantworten, aber hier gehe ich. Ich hoffe, ich bekomme keine Punkte für Antworten, das wäre komisch, nur für das Akzeptieren einer Antwort? (Übrigens, ich habe im Element14-Forum keine Antwort erhalten.)

Die Lösung besteht darin, den DRAW-Befehl zu verwenden, nicht ROUTE. DRAW platziert ein Drahtsegment genau dort, wo Sie es angeben (im Gegensatz zu ROUTE, das versucht, eine Verbindung zu einer nicht gerouteten Luftlinie herzustellen. ROUTE ist in einem Skript im Wesentlichen nutzlos.). Das nächste Problem sind Vias: Ich kann (oder will) nicht zwischen einem manuellen Via und einem automatisch gerouteten Via unterscheiden, also behalte ich alle Vias, die zwei (oder mehr) manuelle Drahtsegmente verbinden. Andere Vias werden gelöscht.

Also, was mein letztes Skript tut, ist:

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

Beachten Sie, dass es wahrscheinlich nicht für mehr als zwei Schichten funktionieren wird, noch für andere Dinge als Drahtsegmente auf der Kupferschicht.

IMHO ist das gesamte Konzept der Adler-ULP und der Befehlssprachen problematisch. Ein ULP wird in einer Nur-Lese-Umgebung ausgeführt, die einzige Möglichkeit, wie es sich auf die Schaltung, das Board oder die Bibliothek auswirken kann, besteht darin, eine Liste von Befehlen zu erstellen. Dadurch werden einige nützliche Programmiertechniken eliminiert, aber noch schlimmer ist, dass die Befehle nicht so konzipiert wurden, dass sie einfach von einem ULP erstellt werden können. Sie benötigen alle Arten von Transformationen (in diesem Fall: Koordinaten, Formnamen), um von der ULP-Welt in die CMD-Welt zu übersetzen.

(Bearbeiten) Bevor Sie dieses ULP ausführen, setzen Sie die 'Wire Bend'-Auswahl, um beliebige Winkel zuzulassen, sonst versucht Eagle, die wiederbelebten Drähte an die erlaubten Winkel anzupassen, was zu einem blutigen Durcheinander führen kann. IMHO ist dies ein weiteres Beispiel für das Problem mit ULP/SCR.

Dies ist der ULP-Code:

// 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 );
}
Eagles ULP/SCR sind eine seiner leistungsstärksten Funktionen. Wie Sie festgestellt haben, werden ULPs verwendet, um das Board abzufragen und Skripte zu schreiben, die absolut alles sein können, was Sie selbst tun können. Das ist seine Macht. Allerdings wünschte ich, es wäre in einer „normalen“ Sprache, vielleicht Python oder sogar Lua, aber selbst Sie müssen zugeben, dass es ein gutes Gefühl ist, etwas tun zu können, an das die Autoren der Software nicht gedacht haben.
Sicher, aber ihre Macht muss auf geheimnisvolle Weise ausgeübt werden: ULPs sind mächtig, können aber den Schaltplan/Bord nicht verändern, SCR ist eine verkrüppelte Variante der GUI. Zusammen können sie nützliche Arbeit leisten, aber die Dinge hätten viel einfacher gemacht werden können! Und für mein spezielles Problem wäre es schön gewesen, wenn die vom Autorouter hinzugefügten Dinge irgendwie identifizierbar wären.
In EAGLE v6.3 lautet der Befehl WIRE, nicht DRAW (es gibt keinen DRAW-Befehl).

Wouter. Ich habe Ihre Frage nicht früher gesehen, weil ich letzte Woche beim Masters war.

Ich gehe damit um, indem ich eine Kopie des Boards unter einem anderen Namen speichere, bevor ich den Autorouter starte. Ich nenne es immer SAVE.BRD, das nach Abschluss sicher gelöscht werden kann.

Mein Routing-Workflow scheint Ihrem sehr ähnlich zu sein. Ich route die kritischen Teile manuell, vergewissere mich, dass die Netzklassen vernünftig eingerichtet sind, und führe dann den Autorouter aus. Dann suche ich nach Problemen, z. B. wo der Autorouter keine Lösung finden konnte, er am Ende etwas Unbequemes gemacht hat usw. Ich gehe zurück zur gespeicherten Version (vor Autoroute) und nehme hoffentlich ein paar manuelle Änderungen vor, damit der Autorouter es nicht bekommt in Schwierigkeiten, dann versuchen Sie es erneut. Dies kann je nach Komplexität des Boards 5-10 Mal wiederholt werden. Die ersten paar Autoroute-Passagen dienen hauptsächlich dazu, zu sehen, ob es eine Lösung gibt, und um grob die Problemstellen zu finden. Dafür verwende ich nicht einmal irgendwelche Optimierungsdurchläufe. Die späteren Autoroutes sind mit vollständiger Optimierung, was für mich normalerweise 8 Pässe sind, wobei sich die Kosten über diese Pässe ändern, um die gewünschten Eigenschaften zu erhalten.

Obwohl ich vor jedem Autoroute-Durchgang in SAVE.BRD speichere (und dann die Originaldatei erneut öffne, um damit fortzufahren), versuche ich, das Autoroute-Ergebnis nicht zu speichern, bis ich mit der ganzen Sache zufrieden bin. Das Speichern des Schnappschusses in SAVE.BRD ist jedes Mal ein Sicherheits-Backup, falls meine Finger versehentlich speichern, bevor ich darüber nachdenke.

Es wäre schön, wenn Eagle eine Ripup-Option für den letzten Autoroute-Pass hätte, aber so etwas gibt es nicht.

Ihre Disziplin wird für eine Person funktionieren, die immer diszipliniert ist. Sie könnten vermuten, dass ich es nicht bin. Einmal habe ich autorouted gemacht, dann einige Änderungen an der Schaltung vorgenommen, dann die brd gelöscht und versucht, zurück zur vorautorouted Version zu wechseln. Keine gute Idee ... Jetzt habe ich also mehr oder weniger eine Möglichkeit, die Autoroutung aufzuheben, vorausgesetzt, ich kann die autorouteten Spuren anhand der Breite unterscheiden. Es wäre schön, wenn automatisch geroutete Ablaufverfolgungen ein Attribut hätten, das sie als solche identifiziert.
Seltsamerweise hatte ich am Anfang meines Beitrags "Hi, Wouter" geschrieben, aber der "Hi, "-Teil scheint entfernt worden zu sein.
Ich glaube, das ist ein "Feature", das der Stack-Austausch hat. Sie denken, dass ein „Hi“ am Anfang eines Beitrags nicht erforderlich ist und entfernt werden sollte, um die Dinge „sauber“ zu halten. Ähnlich wie sie in einigen Fällen @Benutzername entfernen ... und genau wie in diesem Fall, in dem ich @ Olin (ohne Leerzeichen) und @ Benutzername nicht in denselben Kommentar eingeben konnte.

Wenn die Datendatei von Eagle dem gleichen Ansatz folgt wie ältere, mit denen ich gespielt habe (z. B. Ihr altes DOS Autotrax), dann hat jedes Tracksegment eine Zeile für sich. Zeilen sind "eigenständig" und können ohne Auswirkung auf irgendetwas anderes bearbeitet oder gelöscht werden. Neuere "bessere" Systeme sind möglicherweise nicht so einfach.

Wenn Tracks unabhängig sind, wie oben, und wenn die Track-Breiten einzigartig sind, sollte es einfach sein [tm], Track-Segmente zu identifizieren und die betroffenen Linien zu löschen.

Schwache Erinnerung sagt mir, dass ich einmal eine Routine geschrieben habe, um Komponentenetiketten zu identifizieren und sie in der Größe zu ändern, zu drehen und relativ zum Komponentenkörper zu verschieben. Track-Identifikation klingt im Vergleich einfach. Speichern Sie eine Kopie, bevor Sie das Programm ausführen !!! :-).

Von welchem ​​Dateiformat sprichst du? Die Eagle-.brd-Datei ist keine Textdatei. Mein Problem mit den Spursegmenten ist nicht, dass ich sie nicht identifizieren kann, sondern dass der einzige mir bekannte Befehl, den ich verwenden kann, zu viel bewirken wird: RIPUP rippt nicht nur das Segment, sondern auch (einige) benachbarte Segmente.
@Wouter van Ouijen - YMMV :-). Nicht per se Text zu sein bedeutet nicht, dass er nicht gehackt werden kann - aber er kann. Ich weiß nicht, wie die Eagle .brd-Datei im Inneren aussieht, und ich weiß nicht, ob Sie ganze Tracksegmente herausreißen und den Rest sicher verketten können - wahrscheinlich nicht. Aber einen Blick wert. Möglicherweise können Sie einen Dateileser und -umschreiber schreiben, der die Datei ohne die unerwünschten Teile intelligent neu erstellt. Es würde davon abhängen, wie bekannt oder bekannt das Dateiformat ist.
Mir ist klar, dass dies zum Zeitpunkt des Schreibens der Frage wahr war, aber die Dateiformate von Eagle sind jetzt einfache XML-Textdateien.