The new Prusa i3 MK2 printer has a nifty XYZ calibration to keep things square.
curious what would be needed to get this ability into Marlin. and what hardware would be needed to add for a machine to take advantage of it
If we have the exact angles, how much to correct, the calculation is quite simple.
Getting the angles automatically is the problem.
I can detect the borders of aluminium disks on my bed, but i can't place this disks better than i can tune my printers geometry. The MK42 bed is the key item. When i can get one i'll make further tests.
I think that on mk2-like heated beds would be easier by using 3 holes from the same line on Y axis as reference.
In the video it looked like they made 9 "markers" for the inductive probe to find. Best guess is they made 9 spots in the copper heater traces larger to give the probe something to home in on. Then they move around near it to nail down the precise location. Not sure how they know they are centered on the circle but if you know where the nine circles are, its pretty easy to do the math to figure out the offsets.
I have an old original Sells Mendel which showed signs of having a XY skew. I only saw this after printing an object that had been cut and the parts where printed side by side. When trying to put them together they didn't fit perfectly. So, I printed two identical 10x10cm frames, just a few mm heigh. Then placed front to front (keeping track of X and Y, so one only is rotate 180° along Y axis) I could measure the skew and then screw the Y rods in the right direction and the right distance (after some calculations for 8mm rods, 1.25mm/turn). After that the parts fit perfectly. I have been thinking about if this could be added to Marlin (print calibration parts to measure). But, I have not needing it after that.
Would it be possible to use the edge of the build plate ? Assuming an Al build plate ? Going up in Z to find the detection curve heading toward the centre of the build plate. Here again assuming the printer can get out of the print bed enough to find the edge...
Once the edges have been found the Z calibration should be easy, get as many points as you want.
This would work with CoreXY, cartesian, and delta, ...
This is something i've been thinking about only a little bit before I learned about the MK42 bed
Since then, what I propose is that the screws used for screwing the bed to the Y axis (assuming a Mendel type Cartesian) be Zinc Plated Steel. OR a a few extra holed countersunk into the bed for zinc plated steel CSK screws.
This, coupled with a capacitive sensor, or a BLTouch which is modified to enable triggering in the pin down state to sense the magnetic field of the Zinc Plated Steel Screw Head.
Like UBL, apply a matrix to the axes, stored in EEPROM? from there the math is relatively straightforward
You can detect one of the edges of the heated bed, you don't need markers.
Maybe we can figure out something similar but without needing a proximity probe. Can a special test print be created and then when measured with a caliper give you values that you enter into marlin to correct for skew
Maybe we can figure out something similar but without needing a proximity probe. Can a special test print be created and then when measured with a caliper give you values that you enter into marlin to correct for skew
I believe this would work very well.
And here is the thing... I don't believe you are going to get the accuracy you need to do this by measuring stuff on the heat bed with a proximity probe. It would seem to me you are going to just get some noise and not a repeatable measurement. Wouldn't it be a shame to start with a very square machine and because your proximity probe didn't measure correctly you do a whole bunch of math to 'correct' the machine and you end up with a non-square machine???
Can a special test print be created and then when measured with a caliper give you values that you enter into marlin to correct for skew
What shape would be ideal to accomplish this? I think we would want something the allows each axis to be correlated to each of the other two axis. And very possibly, on multiple positions of the third axis.
Couldn't just a thin wall square say 100mm x 100mm work
Measure corner to corner and diagonally
Yes. I think so. The reason I'm not absolutely sure is this: Take the case where one dimension is off a little bit. Suppose 100mm on Y prints as 99mm. And suppose the Y axis is at 89 degrees to the X axis. When you measure the numbers, are you going to be able to tell that you have multiple items that need to be compensated?
It is next to impossible to measure the interior angles accurately as a vernier requires a large flat surface to measure off, and the radius, yes the radius of the filament drag as it goes past an ideal 90 turn, changes.
As Josef has probably done himself, you gotta find a method that doesn't have a person in the loop to provide an accurate calibration.
Having calibration points in fixed areas of the bed is definitely the way to go.
The guys at ANTCLABs also think that using zinc plated steel screws with which to measure the the offsets, is a good idea.
For existing beds, a mod could be made of a magnet or chunk of ferrite in a small print that can be mounted on the underside of the bed corners
I don't believe you are going to get the accuracy you need to do this by measuring stuff on the heat bed with a proximity probe. It would seem to me you are going to just get some noise and not a repeatable measurement.
at 0:25 it looks like moving both X and Y to get the center of the spot. by doing it 9 times and comparing the readings with some hard coded measures it should get plenty of accuracy.
I didn't looked for a BOM, but my guess is on a 4mm NPN inductive sensor, AFAIK next step are 10mm ones, which are bigger.
If the measurement is only diagonally. From top left to bottom right and from top right to bottom and the compensation is relative between these two measurements. So that way a machine can be slightly out of calibration (xy steps) so it if printed it at 99mm instead of 100mm i5 wouldn't screw it up. But just comparing two diagonal measurements. Regardless of length
As long as it was meant to print square should work I assume. Creating more of a ratio between the values
at 0:25 it looks like moving both X and Y to get the center of the spot. by doing it 9 times and comparing the readings with some hard coded measures it should get plenty of accuracy.
It would be ideal to have an analog sensor for this. If you go back and forth, you could find the peak signal, and then perhaps go back and forth at 90 degrees from the previous path.
From top left to bottom right and from top right to bottom and the compensation is relative between these two measurements.
Good point. Using the difference between the two diagonals is going to help you figure the calibration distance of the axis as well as the angle.
We don't have the luxury like Prusa do. So many different 3d printer hardware platforms. Bltouch. Fixed z endstop, proximity probe or nothing at all.
Needs to be something less sophisticated then prusa has but more universally usable by all the different users
Perhaps a print with flat corners to help aid a manual measurement with a caliper
We don't have the luxury like Prusa do. So many different 3d printer hardware platforms. Bltouch. Fixed z endstop, proximity probe or nothing at all.
Needs to be something less sophisticated then prusa has but more universally usable by all the different usersPerhaps a print with flat corners to help aid a manual measurement with a caliper
As you already stated, measuring the internal diagonals of a hollow square is a viable option. Not an optimal solution, but better than what we have now, which is nothing.
I am playing around with that diagonal idea. Here are two cross models I am designing just for this purpose. I think it can be hard to measure over a longer distance, so I am aiming at getting it to an easier measure in one place. Print two pieces, put them together and then measure at the other end. I think this could do for compensating a skew, well, then add the parts in Marlin of course but one could make it a one number thing and do the rest in Marlin to calculate the skew amount. Make it as simple as possible...(easy as possible)
The size of these models are as if they where the diagonal part of a 100x100mm square.
XX models.zip
@epatel I see what you thinking. But what about the over/under extrusion of the filament? If that isn't perfect, are the pieces going to fit together in a meaningful way?
@Roxy-3D I though about that a little, and that is why the insert-block and fit-hole are slightly sloped. So that end should become centered. Over and under extrusion will/should be the same at the measure "spikes"...so maybe need to measure a spike and then measure any difference...the value that is interesting is any difference in length...and if the middle spike is longer or shorter (gives the direction of the skew).
That makes sense! That might just work!
I reckon than calibration pieces should be a lot less elaborate
I am all for simplicity. My reasoning for these models goes a little like this.
To measure skew one need a fairly big model, so the difference in diagonal length gets big enough to tell/measure. A big model is also hard to measure accurately. Callipers gets hard to handle, and thin models can flex. And I think we want to measure a very small difference in length. This is my experience of trying to measure a 100x100mm frame. And I think this gets worse the bigger the bed is too (more and more important to get the accuracy of the skew right).
When designing these models I tried to move the measurement problem to a shorter measure distance, at the spikes. I don't know yet if 10x10cm is enough for a good accuracy. This need testing. I also don't have the math ready either. When doing the models I used 4mm as the thickness of the arms and spikes as I think 4mm is usually a good thickness for "stable" pieces.
And a funny thing with these software compensation parts, like MBL, is that one need a really bad printer to test on. :) My RigidBot is pretty squared and I haven't looked into messing with that...yet...
Something that the user would leave mounted to the bed until after measurement was taken so the print doesn't get as distorted.
Probing/finding one edge of the bed is not enough. Otherwise you can not distinguish whether the bed is turned on the y-sled, or if the x and y axis is not at the right angle. We have to find out if it's a turned square (what is completely uncritical) or a rhombus.
Interesting. I printed the models and I see a couple of things to fix. But, I actually noticed a slight skew on my RigidBot with the help of these models. So I imagine I have to fix this now :) I have discussed a little with a colleague at work and I have a new idea. Hard to explain but hope to test it.
So, I have now modelled two pieces and it is my hope that the lines in the "upper" part of these parts can be used to visually interpret to get a number to enter for a skew "function". I will try to print them now and see how this works on my printer. I have checked that Slic3r can slice them and the ruler markings are not removed (0.3mm layer with 0.5mm nozzle).
The theory is a little like this. One should lineup the single marking at one end and look at the markings at the other end. The markings mimic a _slide ruler_, and a perfect fit (no skew) should line up the middle (longer) line perfectly. One of the pieces markings are spread with 1mm steps and the other with 0.9mm steps. If the piece with 0.9mm steps is 0.1mm shorter the first line below the middle lines should line up perfectly.
I hope to test this now and take some pictures of my findings. Comments?
How are these going to be aligned on the bed when you print them? I presume they will each be printed diagonally. And that they will be printed at 90 degrees to the other one's orientation on the bed?
Yes, I have modeled/placed them diagonally, and 90° to each other. Looked fine in Slic3r for me here (first check for me). But, it is 12.26am here so I am a bit slow and could certainly have missed something.
The edge detection will work the same as assuming the MK42 build plate has it's reference points at the same place.
This brings a one up from the i3 mk2, by doing a Z calibration we could kick out any lean forward/backward due to improper Z axis, this off course would need to be calculated manually from a test print.
Using ratios instead of absolute measurements is important here as 20mm might not yet be 20mm depending on filament and other parameters...
Yes, I have modeled/placed them diagonally, and 90° to each other. Looked fine in Slic3r for me here (first check for me). But, it is 12.26am here so I am a bit slow and could certainly have missed something.
No hurry... But I would like to see pictures of them on the print bed. And then in position to make the measurement.
This brings a one up from the i3 mk2, by doing a Z calibration we could kick out any lean forward/backward due to improper Z axis, this off course would need to be calculated manually from a test print.
I suspect this is true. Can you give more detail so it is obvious to people how this would be accomplished?
At work right now, so it will be hard to make a neat drawing, Print 2 (20x20mmx60mm) tower side by side take both of them once printed on a flat surface.
Take both tower and get them as close as possible front and back, then measure the gap vs height. Trigonometry will give you the angles and hypotenuse. I am sure we can come up with a very systematic way to do this.
Or build 2 U shapes, with a slide ruler calculator ruler like proposed previously. Same markers can then be use rotated 90 deg to find the height... Can probably use the ruler next to the reference marks in Z to adjust Z level too.
So, I have now printed and looked at the pieces. From what I can tell my printer has a 0.7mm diagonal difference, skewed to, lets call it the left.
Like this (not scale)

I printed the two models, I call them A and B.


I then lined up the single-line end. Like this

And then by looking at the "ruler" end I believe B is 0.7mm longer than A.

0.7mm because the lineup occur 7 lines from the where the lineup should be, thus 7*0.1mm
I hope this makes sense.
The final test would be to print the parts again after adding the code configured for 0.7mm.
That's genius!
Very nice work!!!!
And I'm sure this idea will get more than its share of push back. But I'm wondering if it would make sense to have this as a built in command for the Marlin firmware. I already have the lower level code needed to do this in the G26 Mesh Validation Pattern command. The benefit of having the printer do it instead of generating an .STL image, slicing, and printing is this: The Printer knows what the diagonal size is. It can just go ahead and use the max distance without the user being involved.
And, if we put a compensation system in place to correct for the error, the printer can easily validate the shift. (And of course, if you don't want memory burned up by this command, you just turn it off and it disappears.)
@Roxy-3D Yes, I agree. Having the pattern included in Marlin could be good + menu option to enter the measured value. Slicers can be picky when selecting small pieces to slice, and here I specifically modelled after my printer setup and how I sliced them (0.5 nozzle + 0.3 layer).
I am currently trying to add a small/rough xy compensation to my printer and make a test print to see if the theories hold up.
Worth noticing about the MK2 http://prusaprinters.org/first-printer-to-automatically-correct-geometry-in-all-axes/
_However when these basic requirements are met, XYZ calibration procedure achieves an accuracy of cca. 0.2 degrees in the skew of the machine axes, which corresponds to a deviation of 0.5mm over the print bed width_
And when calculating the skew on my machine I get it to about off by ~0.25mm sideways at 100mm and that would be about ~0.5mm at 200mm, so my printer would be as good as the MK2 as is I recon.
@epatel I guess it would have to be two separate prints because we want each one to go diagonally and be close to the full length available. I guess we could have the new GCode specify whether you are printing the A or the B piece. Something like G876 A or G876 B ???? If we did this, can we extend it to report the needed correction on other axis pairs?
@Roxy-3D Yes, that could work too. Actually I think going larger also could make use of larger steps for the ruler lines, i.e. 2mm and 1.8mm respectively. Easier to see which lines line-up.
So, I made a small addition to my private repo that I am using for my printer.
https://github.com/epatel/MarlinDev/commit/d314739530601110589ea583d02b18d96101818f
I was looking for where it would make most sense to add this. But as I will be using MBL and this felt like a good "test" place I just snuck it in planner.c. I trust @Roxy-3D to figure out a better place within UBL. But I show it here if anyone want to play with these things.
The calculation is kind of rough but seem to work pretty good I think. It's quite a big simplification of what is going on. But I imagine this gets pretty close. Well, to try to explain how I am reasoning. The diagonal difference is actually 2 times from the actually normal length because what is gained on A is also lost at B, so this has a double effect. Then we are calculating on the diagonal length of a square so the diagonal is sqrt(20000) for a 100x100 "frame" but we skew X from Y so compensate the diagonal effect. Well, this gives the (simplified) formula,
x -= y * (XY_SKEW_DIAGONAL_DIFF) / ((XY_SKEW_FRAME_LEN) * 2.82842712474619009760);
where 2.82842712474619009760 is 2*sqrt(2) (I see now it can be changed to M_SQRT2 * 2.0)
Think I'm gonna be using this in my printer from now on. Might also look into adding the XY_SKEW_DIAGONAL_DIFF to the LCD/EEPROM (so I can easily change this if I move the printer).
There is also another problem. When homed and the skew is to the "left" similar my printer I think one might need to move to X=0 (out a little so X=0 when max Y would be touching the X endstop). I am thinking of those with x endstops that doesn't allow any movement through the endstop. Because movement along positive Y could result in negative X movement. Well, I haven't added this in my "test" as I am using opto endstops.
If the bed is rotated (as opposed to skewed) then:
sin / cos for the angle of rotation is calculated once and cached as 2 floats (i.e., a rotation matrix). These will be used to rotate of every point given to the planner.Planner::buffer_line do rotation/skew ahead of apply_leveling. When enabled, XY is rotated around the center-point using the rotation+translation matrices. The overhead cost is four float multiplications, plus four float additions.Counter-clockwise rotation:

As a component this might also apply constraints accounting for the X and Y real limits.
Rotation/skew probably works as part of the kinematics, so it's transparent to the other layers - homing, probing, leveling, etc.. It should probably remain active until expressly disabled (or if the bed is re-scanned). Eventually the idea is users will align the bed and turn it off, I suppose…?
I don't believe "rotation" is a problem. Rotation wouldn't compensate for a "deformation" so no need to add that transformation. Skew is actually a result of the bed (Y axis) being slightly rotated in respect to the X axis, and a rotation will not compensate for that.
Trew…

This is correct for clockwise rotation also. The only difference is theta will be shifting from 0.0 into the negative numbers (instead of going positive). x' & y' will still get the correct values.
Interesting. I got a note from @Alex9779 about M556 which when I looked at led me here. https://reprappro.com/documentation/ormerod/axis-compensation/#Orthogonal_Axis_Compensation
Food for thoughts...
The axis/axes that need to be translated depend on, on which axis the bed mounted. For example if you would want to fix an Prusa type printer where the Y axis is mounted to the bed you would have an situation like this:
Normaly when you print a square it would look like this:

But if your bed is skewed like this:

Your print will look like a rhombus like this:

But if you translate the movement of the axis not attached to the bed with angle θ you can make it like this:

To translate the X axis only you would use this formula for the X axis only:

Then:
X'= X_cos(θ) - Y_sin(θ)
Y' = Y
Thinking about it further to do a fully automated callibration with just a square aluminium plate: you can first just move y from min to max and detect the edge of the plate first and determining the degrees of plate versus the y-rods as value y_offset_degrees (basically detect 2 corners at y-min and y-max on the same side either at x-min or x-max).
On a second run go around the plate detecting 4 corners ideally but 3 corners is just as good (with the axiom/requiring that the aluminium heatbed plate is rectangular) at y-min,x-max + y-max,x-max and the thirs y-max,x-min and you can calculate the x/y skew perfectly every time using the y_offset_degrees calculated in step 1 :).
No rocket science or special MK2 heatbed with 9 target pads necessary for this feature. A simple aluminium square/rectangular plate is all we need for both x/y skew and bed tramming!
With above algo all you need in hardware is: a proximity sensor + aluminium/steel heatbed plate that is square or rectangular (but even a retractable limit switch on a square glass plate could work if you dont mind hopping up/down too much for detecting the edges).
A bit of math is left out here (simpson rules+pythagoras is likely needed while coding) but nothing too complex to work this out...