Optical Calibration Demo and Three Hours Working on a Bug

It hasn’t been all that good when calibrating sled weight. If I start with a sled weight of 20 lbs, I end up with a sled weight of 10.4 lbs, which is clearly incorrect. I believe this is consistent to your experience.

My hypothesis is the calibration is compensating for very small measurement differences. When I look at your original measurements for the 5 point Holey Calibration, the bottom measurement is 1 mm shorter than the top measurement. I believe the calibration reduces the sled weight by 50% to compensate for this 1 mm difference. I would like to test to confirm. If this is true, sled weight isn’t a very good candidate for calibration, because it is so sensitive.

1 Like

This is the latest optical calibration run with hand entered parameters (no real calibration had been done)

Actual measured Y-Error


Curve fit to a*x^2 + b*y^2 + c*x*y + d*x + e*y + f (please ignore the trace colors, they are inverted)


So I’m thinking a different curve might be needed as the “curve” doesn’t really match all that well… especially along the left and right edges (0 and 30 on the x axis)… It does smooth out the data at least.

The calibration near the top is pretty good (6 inches from top the accuracy is ~ 0.5 mm) but the bottom corners still have issue (~1.2 mm) and I’m think it might be more of a precision issue (friction, sled balance, etc.)


What are you using for chain sag correction and rotational radius as your defaults?

132.75 rotation radius and 33 chain sag.

132.75 with the ring kit or @pillageTHENburn linkage?

ring kit, but I’m passing the cotter pin through the second link to avoid this:

Why not just also just use the second chain king th over the top of the sprocket when setting vertical? That’s what I’m doing to avid the snapped chain issue

1 Like

Yeah, you can do it that way as well, but I had already marked my chains. Either way works.

Agreed. It looks like the equation doesn’t have the appropriate degree of freedom to capture all the displacement curves. It is like a y*x^2 term is needed.

I think that would show up as noise: both up and down from the curve. To me, this looks like the curve equation doesn’t have sufficient degrees of freedom.

I was using something somebody came up with and have absolutely no clue how to change it so it would do something different. So, now I found something else that I think I can use:

I’m just trying to figure out what the form of the equation that it is fitting and how the returned coefficients relate to the coefficients of that equation. There’s got to be a standard way this is done because nobody seems to ask that specific question…

I don’t think a library reference is necessary. If it is confusing, you can create your own polynomial, and implement your own constants. That way there is no ambiguity.

Something like this:
def Poly(x,y,Coefficients):
return c[0]*x+c[1]*x**2+c[3]*y+c[4]*y**2+c[5]xy+c[6]x**2y

It’s numpy that I have a hard time with. It’s not intuitive if you don’t understand its syntax. This is what I’m using.

        dataX = np.zeros(15 * 31)
        dataY = np.zeros(15 * 31)
        dataZX = np.zeros(15 * 31)
        dataZY = np.zeros(15 * 31)
        for y in range(7, -8, -1):
            for x in range(-15, 16, +1):
                dataX[(7 - y) * 31 + (x + 15)] = float(x * 3.0 * 25.4)
                dataY[(7 - y) * 31 + (x + 15)] = float(x * 3.0 * 25.4)
                dataZX[(7 - y) * 31 + (x + 15)] = self.calErrorsX[x + 15][7 - y]
                dataZY[(7 - y) * 31 + (x + 15)] = self.calErrorsY[x + 15][7 - y]
        mx = self.polyFit2D(dataX, dataY, dataZX)

def polyfit2d(x, y, z, order=3):
    ncols = (order + 1)**2
    G = np.zeros((x.size, ncols))
    ij = itertools.product(range(order+1), range(order+1))
    for k, (i,j) in enumerate(ij):
        G[:,k] = x**i * y**j
    m, _, _, _ = np.linalg.lstsq(G, z)
    return m

and I get back a bunch of coefficients. How would I put in my own polynomial in that?

1 Like

I didn’t test it, but this is how I think it should work, based on what the website describes the output of “itertools.product”.

1 Like

As you guys know, my biggest concern with the optical calibration approach has been the question of how you get an accurate grid to start with.

I just ran across this video https://www.youtube.com/watch?v=Xi9raT8gyEE which points at this $230 (plus shipping) kit that shows how you can make a very accurate grid without having precision equipment in your shop.

that’s a bit pricy for the kit, but it got me thinking about what’s really needed here.

you need:

  1. a way to drill straight holes
  2. at least two guides that have evenly spaced holes, at least 5 holes at the spacing you want the resulting marks (the longer the better, as long as you have at least 3 holes across your minimum distance and 4 across your maximum distance) The exact hole spacing doesn’t matter, what matters is that the holes are all in a straight line and the spacing between them is exactly the same (both on each guide, and the guides match)

by definition, we have a router that can be used to drill straight holes, or you can use a drill press, or a drill guide ( such as https://www.rockler.com/portable-drill-guide or even https://www.rockler.com/jig-it-drill-guide)

to make the holes the same distance along the guides:

  1. make a positioning jig. The jig needs to have a flat board (say 1x4) as the base, a little longer than what you want the hole spacing to be, and a rail along one edge (ideally the thickness of your guide material, or 2x the thickness so you can create two guides at once)

  2. position a temporary fence to allow the jig to move side to side, but not at right angles to the rail

  3. clamp your guide material to the jig against the rail (and the rail against the fence), drill a hole through the guide material and the jig near one end. put a pin through this hole (the tighter the fit the better[1])

  4. unclamp the jig and slide it down the rail the distance you want the holes to be spaces, clamp the jig down well (it will not need to move again, so you can screw it down) and drill another hole.

  5. pull the pin, slide the guide material down so the hole you just drilled is over the other hole, put the pin back in, drill the next hole.

  6. repeat step 5 until you are at the end of your guide pieces.

now follow the directions in the video to drill the holes. In our case, we don’t need the larger holes, so we don’t need the second jig shown in the video[2]

I know there were more problems seeing the holes than seeing crossing lines. that can be dealt with by either increasing the contrast, backlighting the holes, or putting a target in them (either a visual target or a grounded target to probe). at least you are starting out with an accurate target grid.

I’ll try to make some pictures of what I’m talking about in the next few days, but there are others here who make better pictures than I do

[1] to increase accuracy, you should either use a guide material that your drill is not going to distort as you are drilling the calibration holes, or you could drill the holes larger than your pin and use bushings like https://www.atlasbronze.com/product-p/s841bsf-816-10.htm in the holes. I would suggest getting something like https://www.homedepot.com/p/Everbilt-96-in-x-1-in-x-1-4-in-Aluminum-Flat-Bar-802547/204273941 or https://www.lowes.com/pd/Swanson-Tool-Company-Straight-Edges-6-ft-Metal-Ruler/50438214 or go to a metal supply house and get a 10’ length of aluminum or steel bar, or use a bunch of bushings in wood

[2] if you do want to make larger holes, make another guide piece that’s wide enough to mount your router on (with the same hole spacing as your guides, so remove the rail from your jig and use a fence to keep lined up) that’s at least 4 holes long. mount your router to this new guide piece so that it’s exactly lined up with one of the two center holes, fasten the router base to the guide. now you can put a 20mm or a 3/4" bit in the router and plunge though the guide to drill your holes. start off as shown in the video, but instead of needing the special offsets, get/make a head on your pin that exactly matches your larger holes (something that looks like the small pins shown in the video). if you have a small hole in your workpiece, use the small end of the pin as shown in the video. If you have a large hole, put the large end of the pin in the hole, with the pin sticking up for your guide, it will hold things in place.

P.S. with the news of the Pi 4 coming out, it occurs to me that the pi camera module v2 is 8k, and it’s very flat. so it would be easy to 3d print a holder for it that had a 1/2" shaft to mount in the router. put a pi on the sled with the camera, talking to a pi running webcontrol via wifi, you should be able to use the off-the-shelf video tools to track the hole and tell you their coordinates, and you can calibrate it by drilling a hole, keeping the router in place (clamped down if needed) while you replace the bit with the camera, and looking where the camera then sees the hole (you need to keep the camera from rotating, but with the wide ribbon cable of the Pi camera, that’s easy enough to tape down)


I threw a quick model together in onshape at

this is setup for 5" hole spacing, but nothing in this setup is sensitive to the

this shows things in the positions for drilling the first, second and third
holes (steps 1-5) and you can see the jig alone in the parts studio and see the
large hole jig with router-like-thing on it. hopefully you can see how the
complex pin would work with a 3/4 hole vs a 1/4 hole

note, this approach works equally well with 6mm and 20mm holes

David Lang

I haven’t had a chance to review the video and assume there’s no cumulative error built up… But any regular pattern will work, however you get it.

Yes, one difficulty I ran into with holes was that there wasn’t always a good distinct edge that the software could use to recognize the boundary. What I had to do was to fill the inside of the hole with black paint and then paint the outside with white paint. It really wasn’t a problem initially with my first camera because it had fairly low resolution and the image from the camera just seemed to work as-is. But when the LED on it failed and I bought a newer one with higher resolution, it started to see the details of the wood grain and the software had difficulty getting a good fix on the hole itself. I think, as you said, if you make a pattern with drilled holes, you will likely have to do some work to get the camera to be able to accurate detect the boundaries of the hole.

were you using a vision library with object detection (such as opencv)?

David Lang

Yes. The process was adapted from the procedures used for this tutorial.

What about using a sheet of readily available and affordable pegboard which was has a precision machined grid on it already?

There are some good videos on YouTube showing people using this as an indexed jig to make 20mm precision dog hole worktop with a router bit.


1 Like

I’ve found there’s enough variation within the board itself with what you find at the big box stores that it won’t work very well… that and that holes are really hard to recognize well…

I’ve started working on a more robust version that uses a custom library of ArUco codes.