Holey Triangular Calibration

I gave a try at the gcode and modified RunHoleyCalibration.py with my parameters and measured values.

Note: Post 159 does not talk about measurement M12 and I had to search for that which I found into your most recent reply (to @mishle)

I slightly modified the SixHoleCalibrationCut.nc file to score only 1mm deep and raise 2mm above surface. And I got 500mm/min feedrate there but there is no reason to limit it like that.

Test A: I ran the Gcode on my best tuned setup including a residual correction table where I had tweaked the last bit of variation I was able to measure.

Test B: I ran the Gcode again (with a home position 10mm shifted on the right to avoid overlaping) but this time with no correction table values (a correction table value set to all (0,0))

Test A results:
HoleyWithCorrTable.txt (1.9 KB)

File excerpt:
Distance Between Motors:

Motor Y Offset:

Left Chain Tolerance:

Right Chain Tolerance:

Test B results:
HoleyWithoutCorrTable.txt (1.9 KB)

File excerpt:
Distance Between Motors:

Motor Y Offset:

Left Chain Tolerance:

Right Chain Tolerance:

Now what do you think of that?

1 Like

They both look very good.

In your WithoutCorrTable result, the highest error is ~0.54 mm. Considering how difficult it is to measure within 0.5 mm accuracy, I think that is very good. In my calibration, the highest error was ~1.3 mm. So, your calibration looks is better than mine.

Your two calibrations resulted in very similar machine parameters. I would typically use that as a gut-check. You shouldn’t get substantially different machine parameters, as long as the machine doesn’t change. So, this is a good thing.

All evidence suggests you have a very good machine calibration. I would like to see how it does with the Zipper Tree Challenge.

Further, looking at your initial measurements, they were very close to the ideal lengths. Your initial calibration was very good, too. It looks like this calibration only adjusted measured length errors by ~0.5 mm.

Thanks for doing this. I would really like to see my work positively impact others. Your successful calibration is a big step toward that.


170 posts on this topic. What a journey!

I suggest to summarize the Holey Calibration approach as a list of improvements (currently under test) that could eventually make it to the current firmware and GroundControl.

a) An improved firmware taking into account previously missing but important machine parameters to get accurate sled positioning: chain elasticity, sled and chain weight. Once included, it is believed the machine tuning space would now cover the solution space.

b) An improved firmware now computing chain sag compensation based on catenary equilibrium and actual physical weight properties of the suspended apparatus. That is instead of using a parabola approximation. That might ease sag adjustment by eliminating one parameter.

c) A new standard workspace scoring cnc path to reveal the Maslow positioning errors on the workspace. (SixHoleCalibrationCut.nc). in a way that enable efficient measurements collection and parameters optimization function.

d) A standardized 12 points tape measurement operation to assess and list observations of the Maslow positioning errors from the scoring cnc path. This to translate the scoring path into a suitable input to the parameters optimization function.

e) A calculation tool (python script) to generate optimized MaslowCNC settings from the 12 points measurement.

And as a future feature, the calculation output could eventually be automatically proposed to the cnc operator then, upon acknowledgement, pushed to Ground Control’s settings pane and to the firmware for storage.

Do I miss one?

Now, as we can expect, demonstrating each feature fitness to the community needs, execution reliability of the implementation, and providing code improvement modularity to be pulled separately into the MAslowCNC repository, are a few of the important steps to get into the release.

One step at a time,


@c0depr1sm, I think all those comments are pretty much right on.

I keep thinking we can let the results speak for themselves. I consider your story a success, especially in comparison to the current standard calibration. It may be a little early, but one could say that you’ve achieved the Maslow goal of 0.5 mm accuracy. I think that is a huge step, and opens up quite a few doors for Maslow users. I have seen several threads where the Maslow was used for this part, but not that part, because the Maslow was considered inaccurate, not fit for the cuts that required accuracy.

It is difficult to glean any information about fitness or robustness without community trial. There are some additional things we can do to enable that. I wonder if it makes sense to enter this as an alternative calibration process in the Wiki.

1 Like

That would be great!

Here are updated and consolidated instructions.

There is a fork on GitHub which is functioning. If you would like to use it, you will have to be willing to open a python script and modify text as part of the calibration process, and install the Python scipy package (which is pretty straight forward). Otherwise, it is very similar to going through the current triangular calibration. I would like to get one or more other individuals using it, to further demonstrate its viability and create some interest, to get it into the main distribution.

Calibration Process

  • Download and install GC and the Firmware from the above locations
  • Install numpy and scipy Link to Instructions
  • Install the Firmware on the Arduino.
  • The sled-weight is measured using a scale (lbs).
  • Run Ground Control from the new folder
  • Enter the sled-weight (lbs) into the “Advanced System Settings => Chain Sag Correction Value for Triangular Kinematics”
  • You should start with a reasonable calibration based on physical measurements. Your machine should know a reasonable home position before starting the calibration cut.
    • Measure the motor-to-motor distance by with a tape-measure. Enter the value into “Maslow Settings => Distance Between Motors”
    • Measure the distance between the top of the worksheet and the motor-centers. Enter the value into “Maslow Settings => Motor Offset Height MM”
    • Go through the “Actions => Set Chain Lengths - Automatic” exercise.
  • There is a file, SixHoleCalibrationCut.nc in the folder, GroundControlUpdate/gcodeForTesting which drills the holes for the calibration. Set it up on your machine and run it.
  • Measure the center-to-center distance between holes as is shown in the figure in this post
  • There is a file in the Ground Control download named RunHoleyCalibration.py .
    • Open it.
    • There is a section where the initial machine parameters are entered as text, from lines 6 to 13. Type your initial machine parameters in the appropriate locations.
    • There is a section where the measurements are entered as text starting at line 24. Units are in inches. Enter your measurements, top to bottom, where M1 is on top and M12 is on bottom.
    • Run the script.
  • It will print out a calibration result. It will report optimized values for: Distance Between Motors, Motor Y Offset, Left Chain Tolerance, Right Chain Tolerance.
  • Copy-paste the values from the report, into the appropriate GC settings.
  • Force the firmware to update
    • Disconnect and reconnect the arduino by unplugging the USB cable, and re-plugging it in


Got my acrylic today for my new ‘low CGZ’ c-beam spindle sled. Can’t wait to try this! Thanks!


Is this in-sync with the latest version?

I just got back to the shop today so I’m going to read through these posts and see what I can do thanks for all your help

not all 4 by 8 sheets are 48 in tall so would it be better to do our measurements off the bottom for M12. For an example I have just put a piece of MDF in which is 49 in

I believe so.

Regarding Ground Control, when I look at the revision history of my repository, I see the latest commit from the main trunk was a version number bump by @bar on Nov 1, 2018. Since then, there has been one commit to the main fork which was another version number bump by @bar on Dec 2, 2018.

Regarding the Firmware, the only revision that has been made to the main fork is a version number bump on Dec 2 by @bar.

Whatever you measure to is going to become the top-edge of your machine. If the 49" width puts your calibration 1" higher than the machine’s edge, I recommend subtracting 1" from your measurement.

This particular measurement does not interact with the other parameters. It just results in the calibrated top-beam height being shifted up or down.

These are my results.

cal.SP_chainOverSprocket=0 I did not know what to set this as so left it default my chain is over the top then down the side

My sled weight is 21lb 14.1Oz. I put this at 22lb because of the vac hose weight.

RunHoleyCalibrationmishle2.py (1.0 KB)

mishle6@openbox:~$ python /home/mishle6/Documents/GroundControlUpdate/RunHoleyCalibrationmishle2.py
Optimized Errors
Index : 0
Points Span : 1 to 2
Measured Distance : 957.659375
Calibrated Distance: 960.41531595
Distance Error : -2.75594095023
Index : 1
Points Span : 2 to 3
Measured Distance : 957.659375
Calibrated Distance: 959.780032929
Distance Error : -2.12065792933
Index : 2
Points Span : 4 to 5
Measured Distance : 959.64375
Calibrated Distance: 960.413809634
Distance Error : -0.770059634469
Index : 3
Points Span : 5 to 6
Measured Distance : 959.64375
Calibrated Distance: 959.784713788
Distance Error : -0.1409637879
Index : 4
Points Span : 1 to 4
Measured Distance : 703.2625
Calibrated Distance: 703.938865093
Distance Error : -0.676365093027
Index : 5
Points Span : 2 to 5
Measured Distance : 701.675
Calibrated Distance: 703.502821741
Distance Error : -1.82782174126
Index : 6
Points Span : 3 to 6
Measured Distance : 704.05625
Calibrated Distance: 705.036766522
Distance Error : -0.980516522331
Index : 7
Points Span : 2 to 4
Measured Distance : 1191.815625
Calibrated Distance: 1190.21767503
Distance Error : 1.59794997213
Index : 8
Points Span : 1 to 5
Measured Distance : 1193.00625
Calibrated Distance: 1191.05839771
Distance Error : 1.94785229198
Index : 9
Points Span : 3 to 5
Measured Distance : 1194.196875
Calibrated Distance: 1191.91986869
Distance Error : 2.27700631203
Index : 10
Points Span : 2 to 6
Measured Distance : 1189.89230769
Calibrated Distance: 1188.98366025
Distance Error : 0.908647441925

Distance Between Motors:

Motor Y Offset:

Left Chain Tolerance:

Right Chain Tolerance:

1 Like

I am not sure how to interpret this. I am just going to type as I think.

  • The calibration is better than the first one I got with the TriangularCalibration.
  • Overall, if this accurately represents the quality of the calibration, it might not be all that bad.
  • All your measurements are short in comparison to “Ideal”
    • This could be due to the machine’s starting calibration/setup, or it could be due to your measurements.
  • What concerns me is:
    • The measurements are short, AND the calibration defined a positive left and right chain tolerance.
    • I would think the calibration should go the other way. If all the measurements are short, it should define a negative chain tolerance, so that the controller would feed out more chain.

I am having a difficult time with this one. I would like to see if I can reproduce the result. Then I will get back.

Should I measuring between the holes or from the center to center of the holes

The intent is to measure the distances, center-to-center. The most practical way to do this is to measure to the edges of the holes (left-edge to left-edge) or (right-edge to right-edge) or (top to top) or (bottom to bottom)

that’s what I did the first time but then you put the words in between in the instructions so maybe that needs to be changed to say Center to Center

1 Like

OK. I will change it. I apologize.

Hi @Joshua
I was reviewing how I get accurate results and it seems the chain stretch factor is possibly one that could be used to tune up the calibration. My value is 8.1x10E-6 m/m/N. It is the only parameter acting on the top workspace edge dip while changing almost no curve on the bottom edge. It is difficult to estimate and I don’t know how variable it is across various chain supplies.
So I summarized my criticality / measurability analysis and decided to bump a (short) zombie thread just to avoid duplicating that topic or otherwise highjack your topic.

OK. I figured out what is going on. On the calibration/code side, everything worked correctly. I would recommend re-measuring the center-to-center distance between the holes, but other than that, everything is OK.

The chain tolerances are implemented in the kinematics.inverse function. They are implemented such that positive chain tolerance results in a shorter chain. This is a mistake, but it is fully functional and valid. The intent was for a positive chain tolerance to correspond to a stretched chain, however it is the other way around in this implementation.

Moving forward, you’ll just have to be careful. If this is switched in a future version, and you update your software, you’ll have to switch these numbers to negative values. If this happens, I will have to do this, and so will @c0derpr1sm.