Holey Triangular Calibration

I’m starting this thread to document the Holey Triangular Calibration development process.

This process is different than the current process as it determines the exact (as exact as possible) coordinates of each “cut” location. The current process only considers the distance between two cuts at the top, two cuts at the bottom, and between the top of the work area and a cut near the top. It is based upon the assumption that the cuts are perfectly centered. The holey process measures the distances between five holes (one of which is at 0,0) as well as a mark that is directly below the center hole. Using these measurements, its possible to determine the exact coordinates of each of the holes. With these coordinates, there is no need to assume that the cuts are perfectly centered is eliminated and facilitates the use of chain stretch compensation. The hope for the holey process is to improve calibration results.

The gcode to create the holey pattern for a 4x8 sheet of plywood is here (untested as of 8/29/18):

The python code to perform the optimization is here (untested as of 8/29/18):

Right now, you have to manually enter the distances into the code as defined by this terribly exaggerated diagram:


Wow! Holy S%$#!
1 more workday, then Friday/Saturday off for the workshop. Girlfriend kicked out and fridge stocked :beer: Can’t wait to try this out. Any other tests/ measurements I can contribute, let me know.


I really wish there was a way to do calibration that was non-destructive. Plywood isn’t cheap here.


I have time right now, is this something I can test for you? Not exactly sure of the process


Excited to try it, once I figure out how to actually do it. Clearly (I think) the machine has to already be somewhat calibrated (that would mean most everyone on this forum with a working machine). With the sled centered, we copy your code and enter it exactly how? Sorry, have never done that… thinking we could use one of the macros. Then we drill the holes, do the measurements, and add them to your python code? Then what?
This is the “No Judgement” catafory, right?


Yes, but the gcode apparently drills holes about 0.7 inches deep… oops… don’t need to go that deep.

It also puts the sled in the wrong spot after cutting holes (I thought I fixed that but apparently didnt)

The procedure is easy… you can download the files or view them in raw and save appropriately. Load the gcode and run the cutting pattern. It will drill 5 holes.
Measure the distances as shown on the diagram and in the newcal-holes.py file, change the default values for those variables. Make sure you have the number with a decimal place… seems that python treats 1905 as an integer and 1905.0 as a float… they need to be floats. I’m not a python programmer so I might be wrong about that but I just do it anyway.

Save file and from command prompt run python newcal-holes.py

It will show a calculation and pause… hit enter. It will show another calculation and pause… hit enter… it will then go through about 1000 calculations or more and then eventually stop… at this point, it’s reach a minimum solution because everything else it’s trying produces worse errors… eventually it will stop and the speed of that depends upon the speed of your computer. Ctrl+c will stop the program.

put a pencil in the router and mark things that way instead of using a bit.

but the cost of plywood is one reason the cuts are all out near the edge, you
can use the rest of the wood for other things.


Couple things. I drilled a 1/4 hole through my tape measure at 101 mm (was aiming for 100 mm). I left the drill bit in the tape measure hole and then place the drill bit through one of the holes I was measuring from. It works well, but the measurements will be off by a small amount since you cant line up the hole you are measuring to with the center of the tape (not sure if that confuses or not) unless you have a see-through tape. The measurements for Mark 5 are the trickiest.

Right now, I don’t know the chain tolerances calculations are how they should be. I set the tolerance to zero when I ran my cuts and and at end of optimization, my chain tolerance values we’re less than 1. So don’t try these values to see if theres an improvement… I think the numbers need to be inverted based on how Maslow deals with chain tolerance. Ive got a new firmware to test it that manages chain tolerance differently and would work correctly with numbers less than 1.

Yes, this is a feature of Python 2 (Python 3 changes this)

David Lang

When I put in the new firmware and new optimized settings, I was 1/16 inch short 18 inches up from center and dead on 18-inches down from center. I moved to 6-inches from the right edge and repeated. I was dead on 18-inches up from center and 1/16 inch short 18 inches down from center. These are just vertical measurements… I didn’t measure horizontal yet since everyone seems to have vertical issues more so.

But I’ll have to pick up tomorrow or Friday. My z-axis cable got snagged and yanked out of the controller and I lost USB connection. Now I have to reset the chains and all. I’m going to switch to the new chains I got to see if things are better.


You are awesome! Let me know how I can help. Should have most of the weekend to test things if needed.


Do we then enter these calculated values into maslow settings or do we need to wait for your new firmware to test?

I wouldn’t use them right now without different firmware. Just give me some time to see if this thing actually works. Feel free to cut the holes and post your measurements… it’s nice to have other sata points to play with.

1 Like

There’s an error in the chain sag calculations that I’m working on. No point of running the optimization code at this point.

1 Like

@Jatt I use .5 inch x 4’ x 8’ foam insulation board from a local home center for $8 for my calibration. It is foil backed and I cut on that side. I choose the .5 inch thickness because I cut mainly .5”x5’x5’ baltic birch. There are many thicknesses you can get though. The product is similar to this:

1 Like

So to go crazy and further eliminate assumptions, I’ve modified the routine to now allow for independent adjustment of the X, Y coordinates of each motor. Risky, yes. But it eliminates the assumptions:

  • the motors are perfectly level
  • the center point (0,0) is exactly in the middle of the two motors

The latter is important if there is any difference in chain tolerances. If center is not really center then the assumption that it is is wrong and calculations are off.

Part of this was an exercise to see if the optimization routines would settle on a good solution or blow up. Interestingly enough, I was able to get my error magnitude to 0.69 mm with the worse errors being about 1 mm (~1/16th inch). However, optimized values mean less than jack if they don’t produce results and I don’t know that yet. The motor spacing it liked seems higher than I think it really is.

Since the program liked to spread the motors apart, I think I’m going to do something a bit complex… constrain the X coordinates of the motors that so that the motors the distance between motors is fixed, but the X coordinates can shift left and right in tandem or get shifted based upon based upon the “tilt” of the top beam (i.e., if the Y coordinate of one of motors increases, the X coordinates will change based upon the rotation of the top beam). Math is fun.

Using these adjustments, I fixed the motor spacing and fixed the rotational radius. I allowed the top beam to move around (left, right, up, down and tilt) and allowed chain sag and left and right chain tolerances to vary. I restricted the chain tolerances from going higher than 1.0 (in the way I calculate chain tolerance, a number higher than 1.0 suggests the chains are shorter than they should be… which is not logical)

The results are encouraging in that it at least it minimized error value…

Error Magnitude: 0.809
Motor Spacing: 3602.6 (what I measured by hand… this was fixed)
Rotation Radius: 139.1 (what I believe it to be… this was fixed)
Chain Sag Correction: 28.023907
Left Chain: 0.994409
Right Chain: 0.997864
Left Motor X,Y: -1800.6534, -1082.749
Right Motor X,Y: 1801.9455, -1085.525 (this means right motor about 3 mm higher than left)
Left Chain Error Hole 1: -0.985
Left Chain Error Hole 2: 0.9938
Left Chain Error Hole 3: -0.9462
Left Chain Error Hole 4: 0.8875
Right Chain Error Hole 1: -0.7822
Right Chain Error Hole 2: 0.8981
Right Chain Error Hole 3: 0.0702
Right Chain Error Hole 4: -0.4148


X=0 is arbitrary, but it’s specified as being exactly in the middle of the two

chain tolerance shouldn’t change this, you may rotate the two motors different
amounts, but you are still going to be in the center.

making the machine not be symmetric around X=0 will have a LOT of side effects
in the math.

David Lang

Will be back to my machine next Tuesday, and look forward to trying this process, provided I can figure out exactly what you are doing…

  • I am assuming this process replaces the Triangular Test… we go through the calibration routine to that point, then run Holey instead. Or, we can work from our existing set-up, with the idea that Holey will take us a step further.
  • How does the mark happen… is it another hole?
  • Are you using v1.20 firm and software?
  • You are creating new firmware… will this be v1.21? Or will thie be something like v1.20.b, that will work with GC 1.20?

Looking forward to others “making it so” over the long weekend, so I can lurk on in and benefit from all your hard work!

Thanks So Much!!!

1 Like

I will be attempting this tomorrow morning, certainly with hangover cause party tonight.
Still I’m confident to get to play with the python :snake:
Lazy as I am to document I’ll record my screen and have additional screenshots.

Edit: I received 2 new chains from Portland yesterday. Not sure if a comparison to the first beta-tester batch will help. I will compare them and also try to see a difference of turning the 16 months used ones to slack side.

1 Like