The autorouter is incompatible with the trace optimiser
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
gEDA project |
Confirmed
|
Medium
|
Unassigned | ||
pcb |
Confirmed
|
Medium
|
Unassigned |
Bug Description
The autorouter creates traces that are incompatible with the trace optimiser mitering function. The attached PCB file shows the problem.
Affected versions:
20091103 compiled from source on Linux
GIT head downloaded 4th Feb 2010 & compiled on Linux
Steps to reproduce:
1. Load attached file
2. Trace Optimiser -> miter
3. Observe failure to miter
Alternate steps to reproduce:
1. Load attached file
2. Delete existing traces
3. Optimise rats
4. Select rat
5. Autoroute selected rat
6. Trace Optimiser -> miter
7. Observe failure to miter
Initial diagnosis
The autorouter creates traces that have tiny gaps (around 0.01 mils) that prevent mitering. Loading the attached PCB file shoes that the autorouter creates
vertical and horizontal lines *mostly* lie on a 1.00 mil grid, but occasionally the lines are off grid by 0.01 or 0.02 mil. These gaps are generally too small to see,
but are big enough to prevent the trace optimiser from mitering.
Changed in geda-project: | |
importance: | Undecided → Medium |
status: | New → Confirmed |
tags: | added: autorouter |
Better diagnosis:
I've checked further and found that the problem is not that the autorouter makes tiny gaps, it is actually the opposite problem - the autorouter often makes small "overhangs" where a line segment slightly "overshoots" the intersection with another segment. These overhangs are tiny - typically 0.01 thou. Unfortunately these overhangs are enough to prevent mitering.
Workaround
The following patch against the head of the repository extends the trace optimiser "simple" optimization function to remove the overhangs. This means that mitering becomes possible by performing "trace optimiser -> simple optimisations" after autorouting operations.
diff --git a/src/djopt.c b/src/djopt.c
index 68b3641..8422a20 100644
--- a/src/djopt.c
+++ b/src/djopt.c
@@ -75,6 +75,10 @@ RCSID ("$Id$");
#define ORIENT(x) ((x) & 0xf0)
#define DIRECT(x) ((x) & 0x0f)
+/* square of the length of the longest "freckle" */
+#define LONGEST_FRECKLE 3
+#define SQ(x) ((x) * (x))
+
struct line_s;
typedef struct corner_s optimize_ corner (corner_s * c)
@@ -1230,6 +1234,18 @@ simple_
}
}
check (c, 0);
+ if (c->n_lines == 1 && !c->via)
+ {
+ /* see if it is a "freckle" */
+ corner_s *c0 = other_corner (c->lines[0], c);
+ if (SQ(c->x - c0->x) + SQ(c->y - c0->y) < LONGEST_FRECKLE)
+ {
+ dprintf ("freckle %d,%d to %d,%d\n",
+ c->x, c->y, c0->x, c0->y);
+ move_corner (c, c0->x, c0->y);
+ }
+ }
+ check (c, 0);
return rv;
}