在Eagle中将手工路由和自动路由相结合;Eagle ULP中的选择性撕裂


8

在Eagle中,我通常更喜欢自己布线(电源线,xtal,UBS等),而其余的则留给自动布线器。当我对结果不满意时,我自己再路由一些,然后让自动布线器再试一次。

我的问题是撤消自动布线器的工作,而不撤消我自​​己的工作。做到这一点的基本方法就是不保存自动布线的版本,然后再次加载电路板。但是一旦我犯了保存自动路由版本(清除备份)的错误,我仍然希望能够返回到自动路由版本。

一种尝试是在ULP中标识所有自动布线,并创建命令字符串以对这些网段进行RIPUP。我可以安排ULP识别自动布线,例如通过给它们指定不同的宽度。但是RIPUP命令似乎会撕裂选定的线段和相邻段。到目前为止,我还没有找到仅撕裂所选线段的命令。

因此,我想我有两个问题:-您如何以迭代(试错)的方式结合手工路由和自动路由?-是否有一种方法(可能使用ULP和命令)来分割线段的子集?

(更新)我尝试了相反的方法:在ULP中,收集我要保留的所有线段,进行完整的分割,然后还原线段(使用ROUTE命令)。没有成功,这些段必须按照特定的顺序来执行路由命令(而不是ULP找到它们的顺序:(),必须先制造通孔,否则还会出现其他问题。

GRRRR,一定有一个简单的方法可以做到这一点,否则我是否过于乐观?


如果Eagle的数据文件采用与我以前使用过的旧文件相同的方法(例如,旧的DOS Autotrax),则每个轨道段都有一条线。如果磁道宽度是唯一的,则[tm]应该易于识别磁道段并删除相关的行。昏暗的记忆告诉我,在一个阶段,我编写了一个例程来标识组件标签,并相对于组件主体调整大小,旋转和移动它们。音轨识别听起来比较容易。运行程序之前保存副本!:-)。
罗素·麦克马洪

这是一个了不起的问题,可能我建议您也将其发布到Eagle的Element14专家上element14.com/community/message/5177。如果您找到了任何东西,请返回此处!
vicatcu,2011年

OK完成。如果失败,我可以尝试eagle论坛。
Wouter van Ooijen 2011年

Answers:


4

我讨厌回答我自己的问题,但是我走了。我希望我不会因为回答而获得积分,那只会因为接受答案而很奇怪?(顺便说一句,我在Element14论坛上没有得到任何回应。)

解决方案是使用DRAW命令,而不是ROUTE。DRAW将在您指定的位置精确地放置一个线段(与ROUTE不同,ROUTE尝试连接到未布线的航空线。ROUTE在脚本中实质上是无用的。)。下一个问题是通孔:我无法(或不想)区分手动通孔和自动布线通孔,因此我保留了连接两个(或更多)手动线段的所有通孔。其他通孔被删除。

所以我的最终脚本要做的是:

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

请注意,它可能不适用于两层以上,也不适用于铜层上的线段。

恕我直言,鹰式ULP和命令语言的整个概念很麻烦。ULP在只读环境中运行,它影响电路,电路板或库的唯一方法是创建命令列表。这消除了一些有用的编程技术,但是更糟糕的是,这些命令的设计不易于从ULP创建。您需要各种转换(在这种情况下:坐标,形状名称)才能从ULP世界转换为CMD世界。

(编辑)在运行此ULP之前,请设置“电线弯曲”选项以允许任意角度,否则Eagle会尝试将复活的电线调整为允许的角度,这可能会导致流血的混乱。恕我直言,这是ULP / SCR问题的另一个示例。

这是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 );
}

Eagle的ULP / SCR是其最强大的功能之一。如您所见,ULP用于查询板并编写脚本,这绝对是您自己可以做的任何事情。这就是它的力量。话虽如此,但我希望它是一种“普通”语言,也许是Python甚至是Lua,但是即使您必须承认,能够做一些软件作者没有想到的事情也是一种好感觉。
akohlsmith

可以,但是必须以神秘的方式使用它们的能力:ULP功能强大,但无法更改原理图/边框,SCR是GUI的残缺变形。他们在一起可以做有用的工作,但事情本来可以轻松得多!对于我的特殊问题,如果自动路由器添加的内容能够以某种方式识别,那就太好了。
Wouter van Ooijen

2
在EAGLE v6.3中,该命令为“ WIRE not DRAW”(没有DRAW命令)。

2

哇 上周我在美国名人赛上,所以我之前没有看到您的问题。

我处理此问题的方法是在运行自动布线器之前立即将板的副本保存为其他名称。我总是将其命名为SAVE.BRD,一旦完成,可以将其安全删除。

我的路由工作流程似乎很像您的工作流程。我手动路由关键部分,确保合理设置网络类,然后运行自动路由。然后,我寻找一些问题,例如自动布线器找不到解决方案,最终导致某些不便之处等等。我返回保存的版本(在自动布线之前),希望进行一些手动更改,以使自动布线器不会出现问题遇到麻烦,然后重试。可能会重复5-10次,具体取决于板的复杂程度。自动布线的前几步主要是查看是否有解决方案,并大致找到问题点。为此,我什至不使用任何优化过程。后来的自动布线是经过全面优化的,对我来说,通常是8个通行证,而在这些通行证上进行成本转换以获得我想要的特性。

即使我在每次自动路由通过之前都保存到SAVE.BRD(然后重新打开原始文件以继续执行该操作),但我还是尝试不对自动路由结果进行保存,直到对整个过程感到满意为止。每次将快照保存到SAVE.BRD都是安全备份,以防万一我的手指在考虑之前不小心进行了保存。

如果Eagle在最后一次自动路由传递中具有ripup选项,那就太好了,但是没有这种事情。


您的纪律将为始终受纪律的人服务。您可能会猜测我不是。一旦我自动路由,然后对电路进行一些更改,然后删除brd并尝试切换回预自动路由的版本。这不是一个好主意。所以现在,我可以或多或少地取消自动布线,只要我可以按宽度区分自动布线的迹线。如果自动路由的跟踪具有某些属性可以标识它们,那就很好了。
Wouter van Ooijen 2011年

奇怪,我在文章开头写了“嗨,Wouter”,但“嗨,”部分似乎被剥夺了。
奥林·拉斯洛普

我相信这是堆栈交换具有的“功能”。他们认为不需要在帖子的开头说“嗨”,应该删除它以保持内容“干净”。与它们类似,在某些情况下会剥离@username ...,就像这种情况下,我无法在同一注释中键入@ Olin(无空格)和@username。
2011年


1

如果Eagle的数据文件采用与我以前使用过的旧文件相同的方法(例如,旧的DOS Autotrax),则每个轨道段都有一条线。行是“独立的”,可以对其进行编辑或删除,而不会影响其他任何内容。较新的“更好”的系统可能没有这么强大的简单性。

如果磁道是独立的(如上所述),并且磁道宽度是唯一的,则[tm]应该易于识别磁道段并删除相关的线。

昏暗的记忆告诉我,在一个阶段,我编写了一个例程来标识组件标签,并相对于组件主体调整大小,旋转和移动它们。音轨识别听起来比较容易。运行程序之前保存副本!:-)。


您正在谈论哪种文件格式?eagle .brd文件不是文本文件。我对轨迹线段的问题不是我无法识别它们,而是我知道我可以使用的唯一命令会做太多事情:RIPUP不仅会撕裂该线段,还会撕裂(一些)相邻的线段。
Wouter van Ooijen 2011年

@Wouter van Ouijen-YMMV :-)。本身不是文本并不意味着它不能被黑客入侵-而是可以。我不知道Eagle .brd文件的内部外观是什么,也不知道您是否可以撕开整个音轨段并将其余部分安全地连接起来-可能不是。值得一看。您也许可以编写文件读取器和重写器,从而以较少的不良部分智能地重建文件。这将取决于文件格式的知名度。
罗素·麦克马洪

我意识到在撰写问题时确实如此,但是Eagle的文件格式现在是简单的XML文本文件。
akohlsmith
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.