Skip to content
URIAH CLEMMER
$ cat blog/the-largest-cylinder-that-fits.md

The largest cylinder that fits

SOFTWARE VENEER 11 min read

A veneer block — a log section four or five feet long — is lifted into a charger and gripped between two spindles. The charger turns it one full revolution. While it turns, a laser line is projected along its length and two cameras photograph the line about ninety times, and from those pictures the software builds a surface of thirteen to fifteen thousand measured points around and along the log. From that surface it works out the one thing the lathe needs to know: the axis of the largest cylinder that fits inside the wood. Then it tells the charger's controller how far to shift each end of the block — left, right, up, down, in inches — so that axis lines up with the lathe, and sends the lathe the cylinder's diameter so it knows when the block is round.

That is the XY block-centering system at the Freeman Corporation, and it is the first piece of what is becoming Production Manager: software for running a rotary veneer line, which the write-up on the peeling recipe described from the other end. This post is about the centering, because it is the piece that exists, and because in a fortnight of September it went from a method that was wrong by exactly half to one that can be checked against a tape measure. It is C#, it talks to a PLC, and like the Bundle Grader write-up it is written for the engineering and not the business.

Why the axis matters

The lathe's spindles are fixed. A block spun on them rounds up when the knife makes full-width contact, which happens at the radius of the largest cylinder that fits inside the wood about the lathe's axis — and every inch of radius between where that cylinder sits and where the block could have rounded up, had it been spun on a better axis, is roundup waste. It comes off as broken, useless veneer before the first full sheet. So the charger's job is a geometry problem: find the axis that maximises the inscribed radius, and put the block on it.

ONE TURN, ONE LASER LINE, TWO CAMERAS head camera tail camera laser line along the length · its height in each column is a radius one full turn ~90 frames · 13–15k points the axis of the largest cylinder that fits inside the wood to the PLC, in inches: head move (X, Y) · tail move (X, Y) · inscribed diameter → roundup · largest radius → carriage retract schematic · not to scale

Measuring the surface is laser-line triangulation. The line is projected from above at an angle, and where the block's surface is higher the line sits higher in the camera's picture, so the line's height in each pixel column is a radius once you know the conversion. The conversion came from scanning two cylinders of known diameter and a cable stretched taut along the spindle axis for the zero — two points and an origin, a piecewise-linear map. It was one map for every column, and the first thing the September review found was that the head camera read about three pixels higher than the tail camera for the same cylinder, on both cylinders: a fixed offset of about 0.3 inches of radius between one section and the others. A calibration that is the same for every column cannot see that. The constants map was off by up to 0.395 inches somewhere along the block; a per-column table, three fitted lines per camera half from the same calibration frames, read the cylinders within 0.094; and after a correction from a block that had already been rounded on the lathe — a true cylinder of a tape-measured radius, scanned nine times and re-chucked between — the worst error over the block's length was 0.031 inches.

Two more things the old scan assumed

The cameras fired at a fixed rate, and the code assigned each frame an angle by dividing 360 degrees evenly by however many frames it had. The block does not turn at a constant speed: it accelerates at the start of the revolution and slows at the end, so evenly spaced in time is not evenly spaced in angle, and the error was measured at up to fifty degrees for some frames. A cross-section point placed fifty degrees from where it was measured is not a small error. Each frame is now stamped with the block's true rotation angle read from the PLC, using the camera's own capture timestamp rather than the moment the frame arrived at the PC — because frames arrive in bursts, and the arrival-time angle was wrong by up to twenty-seven degrees on frames where the capture-time angle is smooth.

And the laser line was found by thresholding the picture and thinning the stripe to a one-pixel skeleton, which gives whole-pixel positions and occasionally catches a stray reflection. It is now found by weighing brightness across the stripe — a centroid in each column, good to a fraction of a pixel — which also happens to be about ten times faster: 7 milliseconds a frame instead of 79. With ninety frames a scan, that mattered.

The centroid was wrong by exactly half

Here is the finding that reorganised the project. The original method took the cross-section at three fixed columns — head, middle, tail — computed the centroid of each section's points, drew a line through the centroids and extrapolated it to the spindles. It is the obvious thing to do and it is wrong in a way that is easy to prove.

Take a perfectly round block of radius R whose centre sits a distance d from the rotation axis. The scan samples the surface at equal angles about the axis, not about the block's centre, because the axis is what turns. The measured radius at angle θ is

r(θ) = d·cos θ + √(R² − d²·sin² θ)

mean X = (1 ÷ 2π) ∫ r(θ)·cos θ dθ
       = d·mean(cos² θ) + (1 ÷ 2π) ∫ cos θ · √(R² − d²·sin² θ) dθ
       = d ÷ 2 + 0

The second integral vanishes because the square-root term is symmetric about ninety degrees while the cosine is antisymmetric. So the centroid of the sampled points sits at d ÷ 2 — exactly half the true offset — for any radius and any offset. Every scan corrected half of the block's eccentricity, a rescan would have corrected half of what was left, and the source was full of hand-tuned offsets and comments reading "Worse" and "not it", which is what you get when you tune a method that is structurally half right. A numeric check with an 8-inch radius and a 1.5-inch offset gives a centroid at 0.75. The diameters came out biased the same way, so the roundup diameter sent to the lathe was wrong for every block that was not already centred.

WHY THE CENTROID WAS WRONG, AND WHAT REPLACED IT 1 · a round block, off-centre by d rotation axis true centre · d centroid · d ÷ 2 sampled at equal angles about the AXIS, not the centre 2 · a real section: a flat, a knot knot flat centroid inscribed centre ring between the two circles = roundup waste dashed: smallest enclosing circle · carriage retract

The cylinder that fits

What the lathe needs is not a centroid or even a circle. Take every measured point, and take any candidate axis — a straight line through a point at the head spindle plane and a point at the tail spindle plane, four numbers. The clearance of a point from that axis is its distance from it. The inscribed radius of the axis is the smallest clearance over the whole block, and the axis to send is the one that makes it largest. Three choices had to be made and said out loud.

First, a low percentile rather than the strict minimum. The strict minimum is set by one point: one knot hole, one check, one gap in the bark, and the whole axis chases it. The lathe does not need every point to be wood — a small hole in the first sheets is normal — so the inscribed radius is the lowest half a percent of clearances, about eighty of fifteen thousand points ignored, with the strict minimum and its position logged beside it. Second, a small lean toward the circle-fit axis. On a tapered block the small end sets the inscribed radius and the big end can wander without changing it; the objective is flat along those degrees of freedom and noise would decide them. A penalty of 0.02 inches of radius per inch of departure from the least-squares axis decides only ties, and on a round straight block it is zero. Third, one straight axis for the whole block, not a bent line through three centroids. The lathe has one axis. The search is Nelder–Mead in four parameters from the circle-fit axis, at most four hundred evaluations of fifteen thousand distances each — tens of milliseconds, against a budget of twenty seconds between the end of the scan and the move.

It went in behind a switch, in shadow: compute both, send the old result to the PLC, log both, compare over a shift's worth of blocks. On the rounded calibration block the new axis agreed with the circle fit within hundredths and the inscribed radius read the tape-measured radius less the surface roughness, as it should. On the fourteenth of September it became the default, and the first four production scans passed the three sanity checks written down the Friday before: within 0.15 inches of the circle result, a gain that is never negative, and a green ring inside the wood on every picture.

The other half: is the block where it says?

Measuring the block correctly is one half of accuracy. The other is whether the block ends up where the software said, after the charger's move, a mechanical transfer, and the lathe's own grip — and there is no sensor at the lathe that reports where a block sits. So it was measured by hand. A rounded block is marked while the charger holds it after its move, transferred to the lathe, turned until the mark is up, and a tape is read from the block's edge to the lathe spindle at four places on each end face. Half the difference of opposite readings is the block's offset from the spindle, to about a sixteenth of an inch.

WhereInstrumentWhat it found
The scanA block already rounded on the lathe, radius 6.73 in by tape, nine chuckingsMeasured radius within 0.031 in of the tape everywhere along the block; scan to scan, any point repeats to 0.005–0.04 in
The moveTapes on both spindle housings; the four hydraulic cylinders traced ten times a secondCylinders settle within a couple of thousandths of their targets; the housings move the commanded distance within a sixteenth
The latheA tape from the block's edge to the spindle, four places per end, sixteen cycles over two rounded blocksA fixed 0.33 in toward the infeed at both ends — corrected in the PLC; then a 0.38 in component at the head that turns with the block

The first three cycles found both ends of the block about a third of an inch toward the infeed, the same amount every time, regardless of which way the move had gone or how far the block had been rotated. A gain or sign error in the software's values would follow the move; a bias in the scan would turn with the rotation; this did neither, so it lives in the machine — the transfer, or where the charger's spindles sit against the transfer line — and it went into the PLC's correction offsets. With that in, the sideways error went to under a tenth at the head and between zero and a sixth at the tail.

What was left was stranger. Over ten more cycles across both blocks, including one deliberately rotated a hundred and six degrees differently, the head end showed an error of about 0.38 inches that changed sign with the rotation. Fit three models to the ten readings by least squares: a vector fixed in the block that turns with it, plus a machine constant, fits to 0.07 inches; a linear function of the move fits to 0.135; an isotropic shortfall of the move fits to 0.27. The first wins, and it says that something the same size on two unrelated blocks turns with the block and is invisible to the scan. The tape is read at the block's end face against the spindle shaft. The scan measures the inscribed cylinder of the surface the laser sees along the length. An end face cut out of square, or the stub beside the chuck that the knife never reaches, would do exactly this — and the next test is the one with no end face in it: a dial indicator against the rounded surface a few inches in from each chuck, one turn by hand, half of max minus min. That is where the project stands this week.

What is around it

Every scan is archived — the frames, the extracted lines, the timing — so any result can be recomputed later by a program that never touches the plant, and the whole algorithm runs offline against archived blocks and against synthetic frames with a known eccentric circle, with today's outputs recorded as golden values so every change is checked against them. The first commit of the review was that safety net, before any behaviour changed. Each morning a daily email says what went through the charger the day before and how it did: blocks with a result, scan failures, forced rescans, the diameters as a histogram, the volumes, the size of the moves, and every error line from the log grouped by message — because the log is the only record of failures and restarts, and a bad camera or a database outage should not need somebody to open it. That email is the seed of the rest: the plan is for it to grow one section per machine until it covers the rotary line, with a production database behind it, and for the recipe the peeling post derived to be what the software loads into the lathe rather than what somebody types from a whiteboard. That is the Production Manager on the project card, and the centering is the part of it that is real.

A note on the figures

Both diagrams are schematics drawn for this post, not renderings of any scan. Every number is a measurement recorded in the project's own documentation during September — calibration errors, timings, the tape readings at the lathe — and the maths is the maths as implemented. Production Manager is an internal application at the Freeman Corporation; this is the engineering, not the business, and nothing here describes the plant's configuration, its production volumes, its data, or anything a competitor would find useful.

#machine-vision #veneer #csharp #plc
CONTINUE? Questions about this one? Say hello →