-
Notifications
You must be signed in to change notification settings - Fork 4
/
DeltaCalibrationTools.html
336 lines (302 loc) · 14.4 KB
/
DeltaCalibrationTools.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
<!DOCTYPE html PUBLIC "-//IETF//DTD HTML//EN">
<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Delta Calibration Tools</title>
</head>
<body style="font-family: Arial, Helvetica">
<H6 align=right>150111</H6>
<H1>Linear Delta 3D Printer Calibration Tools</H1>
These are some tools to compute calibration adjustments
for a delta-style 3D printer using the Marlin firmware.
<p>Adjustments are computed for the DELTA_RADIUS and DELTA_DIAGONAL_ROD firmware setting,
and the endstop offsets, as are set by the M666 command in Johann's fork of Marlin.
In both the RichieC and Mr-What forks of Marlin there are commands to save all
parameters in EEPROM.
For the Mr-What fork, the command is like : <PRE>
M666 X-8.43 Y-8.81 Z-8.57 A110 B110 C110 D217.9
</PRE>
Where -8.43, -8.81 and -8.57 are the endstop offsets for the X, Y and Z towers respectively.
Here, the DELTA_RADIUS is assumed to be the same for all towers, and is set to 110 for each of them.
This is a good assumption to start with.
Calibration procedures will be presented which can set these three values independently.
The D parameter is the diagonal rod length.
This is the length from pivot center to pivot center, and should be measured very
carefully with calipers if available.
This is one of the few parameters which is easy to estimate with high precision
from a caliper measurement.
</p>
<p>Users of Johann's fork of Marlin may want to use the auto bed-leveling probe function
to measure levels of the bed height.
If you use pronterface <TT>G29</TT> command the auto-level probe, it will
print information like this back to the console:</p><pre> ...
Bed x: 40.00 y: -60.00 z: 5.24
Bed x: 20.00 y: -60.00 z: 5.07
...
Bed x: -20.00 y: 60.00 z: 5.33
Bed x: -40.00 y: 60.00 z: 5.25
-0.51 0.07 -0.00 -0.10 -0.13 0.04 0.21
...
</pre>
<P>If you have implemented a G30 command that does a single bed height probe,
and no other actions, you can use a gcode script to perform a bed-probe
at arbitrary resolution.
<A HREF="http://boim.com/DeltaUtil/bedProbeRandGrid.pl">
This script</A>
probes around 100 points, 3 times each, in random order to try
and average out any backlash effects.
Parameters can be edited to fit your printbed.
</P>
<P>Be sure to clear any bed-leveling polynomial<PRE>
M668
</PRE>
before running this procedure.
The bed leveling polynomial will leave a residual bias in the Z position
after each G30 probe, providing unusable results.
</P>
<P>In a terminal window, run the follwing command:<pre> perl extractProbeData.pl > myBed.dat
</pre>
It will wait for input.
<br>Copy all of the <tt>Bed...</tt> lines from pronterface, and paste
them into the window running the <tt>extractProbeData.pl</tt> script,
then press <CR>ctrl-D, and the script should terminate.
<p>When complete, the script should have produced a myBed.dat file that has contents like:</p><pre>'
40.00 -60.00 4.53
20.00 -60.00 4.48
0.00 -60.00 4.63
-20.00 -60.00 4.84
-40.00 -60.00 5.05
-60.00 -40.00 5.08
...
60.00 40.00 4.78
40.00 60.00 4.66
20.00 60.00 4.83
0.00 60.00 4.99
-20.00 60.00 5.28
-40.00 60.00 5.44
</pre>
<P><img src="bedProbe3.svg" width="40%" align="right">
This data can be loaded into octave (or MATLAB) with a command like:<PRE>
bed = load('myBed.dat');
</PRE>
It may be a good idea to plot your bed probes:<PRE>
plot3(bed(:,1),bed(:,2),bed(:,3),'+');grid on
</PRE>
and verify that repeated readings of each probe point are within
acceptable tolerance.
</P>
<P>If you use the randomized probe script, with a tripple check on every probe point,
you can average these values with this command:<PRE>
bed = sampleMeans(bed);
</PRE>
and then overlay the mean points with a plotting command like:<PRE>
hold on;plot3(bed(:,1),bed(:,2),bed(:,3),'.r');hold off
</PRE>
Verify than any spread of repeated probes is within acceptable tolerance.
If your readings are not repeatable, it may be an indicator of backlash problems
in the hardware, or a software error.
Be sure that any bed-level compensation is turned off for these probes.
On Johann's fork, the homing command, <TT>G28</TT> should do this.
For the Mr-What fork, issue the command <TT>M668</TT> without parameters to
clear the bed-level compensation polynomial.
</P>
<P>You will want to know the vertical offset from your bed probe
to the nozzle tip.
I recommend homing, <TT>G28</TT> then lowering the nozzle until it barely
catches a piece of paper on the printbed.
Note the Z ordinate of this position with the <TT>M114</TT> g-code command.
Repeat this procedure with the bed probe installed and the <TT>G30</TT> command.
Note the difference in the reported Z ordinate.
This is your probe Z offset.
</P>
<p>If you do not have a bed leveling probe, you can manually check the
nozzle height over the bed, and note the position with the M114 command.
I have a similar script to <TT>extractProbeData.pl</TT> which will
create a data file like the one above from M114
output called <tt>extractM114.pl</tt>.
</p>
</p><h3>Data Analysis in Octave (or MATLAB)</h3>
<p>In a folder containing this code, and the <tt>myBed.dat</tt> file
start up an <tt>octave</tt> session.</p><pre> octave
</pre>
Load the data with a command like:<pre> bed = load('myBed.dat');
</pre>
You may wish to remove the Z axis bias.
In my case, this distance is 12.1mm, so I correct my bed probe data
with a command like:<pre> bed(:,3) = bed(:,3) - 12.1;
</pre>
<P>I have been concerned about a probe with XY offsets from the nozzle,
so I currently use a probe which mounts directly under the nozzle,
and have no XY ofset (but my bed(:,3) offset is 12.1 for the larger probe,
the offset for a typical Kossel-Mini probe is around 2mm).
We are not just measuring bed levels, but placement of the end-effector.
I worry that those XY offsets could be more complicated than our simplified
delta model allows.
The current simplfied delta model treats z offset pretty simply and reliably,
so I am less concerned about Z offset errors.
<p>There are two parameters needed besides the bed probe data
to guess at calibration errors.
They are the length of the diagonal rods, pivot-center to pivot-center,
and the DELTA_RADIUS setting.
Place these values in a structure with commands like:</p><pre> DP.RodLen=217.95;
DP.radius=108.2+[0,0,0];
</pre>
Where the RodLen field is the value of your DELTA_DIAGONAL_ROD setting,
and the radius field is the value of your DELTA_RADIUS macro setting from
Configuration.h.
<p>The calibration error estimate takes some time, and you will not
be able to see the progress messages unless you disable the Octave
output pager:</p><pre> more off
</pre>
<TABLE><TR><TD>
<H3>Tilt-only correction</H3>
<img src="tiltedBed.png" width="40%" align="right">
<P>
On your first scan, the endstop offsets are likely to have a large error,
producing a significant tilt, like the one shown on the right.
<P><FONT size=-1>For this plot, I did not use the <TT>plot3</TT> technique
cited above. I prefer plot3, but they do not show well on the printed page.
For these color-elevation plots, I use commands like:<PRE>
x = [-100:5:100];
xx = ones(length(x),1) * x;
z = griddata(a(:,1),a(:,2),a(:,3),xx,xx');
imagesc(x,x,z);colorbar;axis image
</PRE></FONT>
If you have significant tilt in your bed scan it is a good idea to get the endstop offsets close to
the correct value before performing a more detailed calibration.<PRE>
te = guessDeltaEndstopErr(DP,bed)
</PRE>
The <TT>te</TT> variable returned from this procedure provides endstop adjustment estimates.
Add these values to your M666 X Y Z settings to obtain a (nearly) flat bed scan.
<P>Re-scan the bed after refining the endstop offsets.
</TD></TR></TABLE>
<TABLE><TR><TD>
<H3>Constant DELTA_RADIUS estimation</H3>
<p>Now you are ready to guess the calibration errors for the DELTA_RADIUS
setting, and the endstop offsets together:</p>
<pre> [de,te]=guessDeltaErr4(DP,bed)
</pre>
This should add a correction for any bowl/dome type error you see in the bed scan.
(make a plot of this, and include here)
<P>Add the <TT>te</TT> values to your endstop offsets, as described in the previous section,
and add the <TT>de</TT> value to your DELTA_RADIUS.
e.g. Set DELTA_RADIUS in Johann's <TT>Configuration.h</TT> or use a command like<PRE>
M666 X-8.43 Y-8.27 Z-8.54 A109.8 B109.8 C109.8
</PRE> on Mr-What's Marlin fork.
<P>This procedure produce several diagnostic plots.</P>
<p>To update your calibration, add the towerErr value to your
endstop offsets (M666 setting), and add the deltaErr value
to your DELTA_RADIUS setting.</p>
</p><p>I prefer to get the surface fairly flat before I really trust the
deltaErr value and apply it, as suggested above.</p>
</TD></TR></TABLE>
<TABLE><TR><TD>
<H3>Individual DELTA_RADIUS estimation</H3>
<IMG SRC="potatoChipBed.png" width="40%" align="right">
Make a new scan of your bed, using your best estimate of printer parameters and load it.
<P>After your initial DELTA_RADIUS, bowl/dome, compensation you may be left
with a bed scan which is rather potato-chip shaped.
Not exactly tilted, not exactly a dome.
Setting a unique DELTA_RADIUS for each tower can help reduce this distortion.
Make sure that your <TT>DP</TT> structure contains the settings for DELTA_RADIUS
used to produce your bed scan data<PRE>
DP.radius=[109.8 109.8 109.8]
</PRE>
We can estimate these unique delta radii with the command:<PRE>
[re,te]=guessDeltaErr6(DP,bed)
</PRE>
</P>
<P>As above, the <TT>te</TT> values can be added to your endstop offsets.
The new delta radius estimate, <TT>re</TT>, values can be set with the
<TT>M666</TT> command on the Mr-What fork.
On Johann's fork, you will need to alter <TT>Configuration.h</TT> to have
three DELTA_RADIUS settings, and use them as appropriate when computing
the locations for tower 1, 2, and 3.</P>
</TD></TR></TABLE>
<TABLE><TR><TD>
<H3>Bed tram polynomial</H3>
Once the tower offset and tower radii are fairly well calibrated,
you may still need a bed tramming polynomial adjustment to get
good first layer adhesion.
Take another probe of the bed, and feed the bed probe data
into:<PRE>
c = plotParabolicFit(bed);
</PRE>
This script will, in addition to diagnostic plots, print out
the M668 command you should enter for the bed tramming polynomial.
<P>
When parameters seem to be good enough to print, use <PRE>
M500
</PRE> to save them to the EEPROM.
<HR>
<H2>Full Calibration</H2>
<IMG width="25%" align="left" SRC="flatBed.png">
Once you have the basic bed calibration close enough to print, from the
above procedure you can continue to the full calibration procedure.
<!-- IMG width="20%" align="right" SRC="deltaTestA.png" -->
<IMG width="20%" align="right" SRC="deltaTestB.png">
<P>Clear any auto-bed-leveling (tram) adjustments,<PRE>
M668</PRE>
and perform a thorough bed level probe, saving the data.
Do bed-leveling (tram) adjustments as necessary to be able to print.
Then print the
<!-- A HREF="deltaTestA.scad" -->
<A HREF="calGrid.scad">
calibration object</A>.
<P>The command<PRE>
computeCalDist.pl XYcalPointsB.dat XYcalPairsB.dat > XYcalDistB30.dat
</PRE>
will produce a file of ideal measurements on this test object.
Using the figure shown here, edit this file to show the values of these
distances as measured with calipers.
<P>Do not attempt to adjust for printer spread.
Printer spread will
be estimated and reported as part of the calibration process.
<P>XYcalPointsB.dat needs to be scaled as appropriate for the scale/spacing
of your calibration grid.
This distancs is set by the spc parameter in <TT>calGrid.scad</TT>.
The calPoints file can be computed by the <TT>calGridPointGen.m</TT> octave script. Make sure that the setting for spc in the octave script matches the one used in the .scad file used to generate the .stl model.
<P>Load the bed probe as described above, and adjust for probe sensor offset.
<P>Now you can run a full parameter calibration with a command like:<PRE>
bed = load('myBed.dat');
bed = sampleMeans(bed);
bed(:,3)=bed(:,3) - zProbeOffset;
myDist='dat/dist15A1.dat';
[te,re,de,spread,DP1] = deltaCalXYZ(DP.RodLen,DP.radius,...
'XYcalPointsB30.dat','XYcalPairsB.dat',myDist,...
bed,endStops0);
</PRE>
<!-- IMG width="40%" align="right" SRC="deltaTestA.svg" -->
<IMG width="40%" align="right" SRC="calGrid.png">
where rodLen is diagonal rod length, measured.
radii are the delta tower radii, individual for each tower.
Names of measurement definition files, and cal print measurements.
if you provide endStops0, there is code that will automatically
add the endstop error estimate, te, to these endstops, and print
out the desired M666 command to set all calibration parameters under
<A HREF="https://github.com/Mr-What/Marlin">Mr-What's fork of Johann's Marlin</A>.
Otherwise, you can add the reported error estimates to your settings
for endstops, delta radius (per each tower), diagonal rod length respectively.
</P>
<P>I have been noting some over-fitting on the full calibration process.
The over-fit seems to find a path to smaller mathematical fit error,
but by finding parameters that work with a non-physical RodLen setting.
Work will continue to limit this issue, but for now I am trying to stop
the search at a smaller number of iterations to return the fairly stable
solution found before the silly RodLen valley solution is located.
</P>
<P>After full calibration, you may be left with some residual error
on the bed tram (level-ness of bed).
A trade-off was made between the assertion that the bed is perfectly
flat, and perpendicular to the towers, and distortion in the XY plane.
Fixing XY distortion may have caused some un-leveling of the bed scan.
In order to correct this, Mr-What's Marlin fork provides the ability
to set a bed-tramming polynomial.
The command:<PRE>
c = plotParabolicFit(bed)
</PRE> will provide the M668 command to set this correction,
as well as a diagnostic plot.
<BR>Note that the A term is a constant offset in this polynomial.
If you wish to move the entire print closer to or farther from the printbed
to deal with print adhesion issues, this is most readily accomplished by altering
the M668 A parameter on the Mr-What Marlin fork.
</TD></TR></TABLE>
</body></html>