Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1.1] XYZ Skew correction #8204

Closed

Conversation

Paciente8159
Copy link

@Paciente8159 Paciente8159 commented Nov 1, 2017

Concise Diff

Machine skew in the XY, XZ and YZ planes can be adjusted with comand M852 I J K comand.
Values are stored in EEPROM.

This is a re-commit of #8159 with the changes sugested by @Allted.
This addresses issue #3839 and #5116.

@Allted
Copy link
Contributor

Allted commented Nov 2, 2017

Holy Cow, that was fast you are a Mad Genius. Firmware changes do not come naturally for me and takes a ton of time so congrats on the hard work.
I have been busy but I need to try this out, I saw your TV part and I have an idea for a slightly different style. I hope to get some time and make it to see what you think of it. I really want to see how well I build my printers and how accurate they can actually get.

@Paciente8159
Copy link
Author

Paciente8159 commented Nov 2, 2017

Thanks.
After having an initial solution for the XY plane it was a matter of replicating it for the other axis and extending the math account for the remaining planes.
Has I said this may not work well (or at least be totally accurate) with autolevelling if the machine distortions are to big (specially regarding the Z axis). I think that ideally all operations regarding leveling, skew, etc.. should be performed with matrix operations so that all terms and the influence they have in all axis are properly calculated from world-coordinates to machine-coordinates and then correctly translated back to world-coordinates.

@fiveangle
Copy link
Contributor

fiveangle commented Nov 2, 2017

Cool !

But curious about the instructions to "print a square"...

One of the more useful parts of the many discussions you linked to was (in #5116) to compensate for skew in the bed plane via printed vernier scales. Measuring bed skew with calipers will be wrought with measurement errors.

The XZ, YZ may not have much opportunity to fix that, but on the XY, the vernier method seems like it would be the super easy, most accurate, and wouldn't require a large precision caliper. With this method, we could include a parameter where one just enters length of the measured strip, for example "101.3" (mm) and then Conditionals_post takes care of the XY skew calcs.

Is this worth exploring now during this initial commit ?

Here's the simple OpenSCAD model that generates the vernier skew strips.

I only threw it together, and since then realized that not fixing them to 45-deg to each other (for example if someone generates one for a non-square bed) it would need some tweaks to the scales. But if we arbitrarily chose included STLs of squares of 100, 150, 200, 250, 300, 350, 400 (and then everything outside of this the user would just have to generate their own via the SCAD, or use the more crude caliper method) it would be as easy as slicing and printing the strips, then enter in the skew value, reflash to have XY skew corrected near perfectly. No caliper required :)

What do you think ? If not interested, I can wait until you're done and see about adding this feature later.

@Paciente8159
Copy link
Author

Paciente8159 commented Nov 2, 2017

Your method works if your X axis is accurate meaning that 100mm in the X direction is exactly that.
If so you only have to calculate the theoretical X length side. In a perfect square that would be sqrt(2*(size_of the_stl_vernier_diagonal/2)^2).

Example: for the diagonal of 100mm the theoretical X side is sqrt(2*(size_of the_stl_vernier_diagonal/2)^2) =~ 70,7107

Edit: Also the vernier scales tell you the difference between the two diagonals. To know the length of each diagonal you have add or subtract half the difference between the two of them to the theoretical (stl file) length.

The rest is the math in the config file. I could include that in the code but since there are multiple ways to measure the skewness of the printer and to make it more calculation lightweight for the MCU I left part of the math to the user.

The advantage of the square is that allows you to test not only skew but also the axis dimensional accuracy of your printer/CNC.

Edit: The printed square can easily be replaced by a drawing of a square with a paper and a pen attached on the extruder place. It will still require the caliper or something to measure the produced results.

@fiveangle
Copy link
Contributor

fiveangle commented Nov 2, 2017

I'll impement it afterward then :)

@Paciente8159
Copy link
Author

I'll think on how to ease the user from the math while still keeping it as flexible as it can. ;-).
Suggestions are accepted. If it comes to that I''l resubmit the changes.

@thinkyhead
Copy link
Member

thinkyhead commented Nov 3, 2017

I left part of the math to the user.

Of course, the compiler can calculate these values on behalf of the user, and the result will end up as a constant. Then they only have to input the actual measurements…

#define DIAG_AC 123.4
#define DIAG_BD 123.4
#define SIDE_AD 123.4
. . .

In Conditionals_post.h

#define _GET_SIDE(a,b,c) (sqrt(2.0*sq(a)+2.0*sq(b)-4.0*sq(c))/2.0)
#define _SKEW_SIDE(a,b,c) tan(M_PI/2.0-acos((sq(a)-sq(b)-sq(c))/(2.0*c*b)))
#define _SKEW_FACTOR(a,b,c) _SKEW_SIDE(a,_GET_SIDE(a,b,c),c)

constexpr float XY_SKEW_FACTOR = _SKEW_FACTOR(DIAG_AC, DIAG_BD, SIDE_AD);

@thinkyhead thinkyhead force-pushed the bugfix-1.1.x branch 5 times, most recently from a94a396 to d6e6d43 Compare November 5, 2017 00:40
@thinkyhead thinkyhead changed the title XYZ Skew correction [1.1] XYZ Skew correction Nov 5, 2017
@thinkyhead thinkyhead force-pushed the bugfix-1.1.x branch 3 times, most recently from 6d9cb62 to aa9de2c Compare November 5, 2017 04:26
@Roxy-3D
Copy link
Member

Roxy-3D commented Nov 5, 2017

I think that ideally all operations regarding leveling, skew, etc.. should be performed with matrix operations so that all terms and the influence they have in all axis are properly calculated from world-coordinates to machine-coordinates and then correctly translated back to world-coordinates.

Yes. In a perfect world this would be good. But the problem is the bed is not flat. Linear equations do NOT sufficiently describe it to get good adhesion across the entire bed. Right now, the best answer is to have a topology of the surface of the bed and use that to track the height. (In other words... A Mesh.)

But with that said... We can describe the 'plane' of the bed by using the mesh points and feeding those into a LSF algorithm. And then feed those coefficients into what ever matrix algebra can be used to fix the X, Y and Z skew.

@thinkyhead thinkyhead force-pushed the bugfix-1.1.x branch 4 times, most recently from bdfd811 to 8720f9d Compare November 5, 2017 05:22
@thinkyhead
Copy link
Member

thinkyhead commented Nov 5, 2017

This Prusa MK2 video describes skew compensation pretty well… I'll just leave the link here for future reference.

@Paciente8159 / @Allted — I've done a lot of mods to your original work, and thanks to the power of Github I've pushed all changes back to your branch. The basic changes applied:

  • Add an option to enable/disable the G-code M852 in case users just want to set it once.
    • When the G-code option is off, the values will be constexpr and thus run faster.
  • Add options to set the measurements and let the compiler compute the skew factors.
  • Squish the description down to fewer lines.
  • Add sanity checks to make sure options have been set.
  • Clean up the skew code in the planner.

I'd like to get a little more granular and have it so that users can have just XY skew compensation if that's all they need, and then the other skew factors will revert to constexpr with 0.0 values, and, again, the planner will run a little quicker.

Thanks once again for this submission. It's a longstanding request, and we just needed the right kick to get it started.

@thinkyhead thinkyhead force-pushed the bugfix-1.1.x branch 4 times, most recently from 5266013 to de461dc Compare November 5, 2017 05:48
@batata004
Copy link

I am anxious to try this skew compensation! My question is this: can I execute "M852 I J K" before everytime I start a print? I disabled eeprom in my firmware.

One more thing: I only have mechanical swtich end stops on Z and Y. At X I have an inductor endstop. It's not a fancy printer, will the M852 command work? Or I should add any extra hardware to it?

@thinkyhead
Copy link
Member

can I execute "M852 I J K" before everytime I start a print?

Yes.

Or I should add any extra hardware to it?

No.

@thinkyhead thinkyhead force-pushed the bugfix-1.1.x branch 2 times, most recently from 54081a8 to 4e19c59 Compare November 16, 2017 07:18
@batata004
Copy link

batata004 commented Nov 16, 2017

@thinkyhead can I use M852 without enabling epprom so everytime before a print I execute this command and it saves the result in a variable?

Also, how does the printer will correct the skewness without additional hardware? How only using endstops it can correct the skewness? My printed bed has no sensors or areas where you can probe... I googled M852 and nothing came up... it would be nice to know the requirements to use this command :)

@PolloPequeno
Copy link

PolloPequeno commented Nov 27, 2017

@thinkyhead Will this be merged into the bug fix branch in the next week or so?

@PolloPequeno
Copy link

@thinkyhead I'm getting a compile issue of "crosses initialization of 'float z_raw' " from planner.ccp (line 642). This doesn't happen with Mesh bed leveling, but with UBL (and similiar cross initialization error with the other Auto bed leveling systems I checked).

I'm working from a copied version of @Paciente8159's bugfix-1.1.x fork. Any idea what's going on? I'm very much looking forward to this feature. Thank you all for the work you've put into this.

P.S. I also got some errors from the Skew sanity checks, there are some issues with the brackets. I'm about 1/2 day into learning github so no pull requests in my immediate future!

@thinkyhead
Copy link
Member

I've just rebased this on the latest bugfix-1.1.x so give it another try. It has been updated at the source fork, if you want to download it from there.

@thinkyhead
Copy link
Member

thinkyhead commented Dec 1, 2017

I googled M852 and nothing came up...

@batata004 — That's because it was invented with this PR.

it would be nice to know the requirements to use this command

  /**
   * M852: Get or set the machine skew factors. Reports current values with no arguments.
   *
   *  S[xy_factor] - Alias for 'I'
   *  I[xy_factor] - New XY skew factor
   *  J[xz_factor] - New XZ skew factor
   *  K[yz_factor] - New YZ skew factor
   */
/**
 * Bed Skew Compensation
 *
 * This feature corrects for misalignment in the XYZ axes.
 *
 * Take the following steps to get the bed skew in the XY plane:
 *  1. Print a test square (e.g., https://www.thingiverse.com/thing:2563185)
 *  2. For XY_DIAG_AC measure the diagonal A to C
 *  3. For XY_DIAG_BD measure the diagonal B to D
 *  4. For XY_SIDE_AD measure the edge A to D
 *
 * Marlin automatically computes skew factors from these measurements.
 * Skew factors may also be computed and set manually:
 *
 *  - Compute AB     : SQRT(2*AC*AC+2*BD*BD-4*AD*AD)/2
 *  - XY_SKEW_FACTOR : TAN(PI/2-ACOS((AC*AC-AB*AB-AD*AD)/(2*AB*AD)))
 *
 * If desired, follow the same procedure for XZ and YZ.
 * Use these diagrams for reference:
 *
 *    Y                     Z                     Z
 *    ^     B-------C       ^     B-------C       ^     B-------C
 *    |    /       /        |    /       /        |    /       /
 *    |   /       /         |   /       /         |   /       /
 *    |  A-------D          |  A-------D          |  A-------D
 *    +-------------->X     +-------------->X     +-------------->Y
 *     XY_SKEW_FACTOR        XZ_SKEW_FACTOR        YZ_SKEW_FACTOR
 */

@batata004
Copy link

GREAT! Now it's very well written!!! Just one question, you said "Marlin automatically computes skew factors from these measurements". So where in the code do I type the A,B,C and D for each plane (there are 3 planes)? I couldnt find where I do this.

@batata004
Copy link

Also, do I need to print that square 3 times or just once?

@AnHardt
Copy link
Member

AnHardt commented Dec 1, 2017

@batata004
Have you ever configured a Marlin-Firmware? In the source of this patch the configuration is repeated more than 20 times. Just read.

What should a "square" be good for when calibrating XZ and YZ? It needs a "cube"!
Just think.

@batata004
Copy link

Thanks! But the link in the comment points to a square not a cube!

@PolloPequeno
Copy link

@thinkyhead, Thanks for the rebase!

@AnHardt
Copy link
Member

AnHardt commented Dec 1, 2017

@batata004
For XY a square is completely sufficient. For XZ and YZ you have to measure the squares on the sides of the qube!

@PolloPequeno
Copy link

PolloPequeno commented Dec 1, 2017

@thinkyhead

When I compile with UBL and skew turned on I get this error


sketch\planner.cpp: In static member function 'static void Planner::unapply_leveling(float*)':

planner.cpp:659: error: crosses initialization of 'const float fade_scaling_factor'

         const float fade_scaling_factor = fade_scaling_factor_for_z(raw[Z_AXIS]);

                     ^
exit status 1
crosses initialization of 'const float fade_scaling_factor' 

The sanity checks was also erroring

#error "SKEW_CORRECTION requires XZ_SKEW_FACTOR or XZ_DIAG_AC, XZ_DIAG_BD, XZ_SIDE_AD."

even though, SKEW_CORRECTION_FOR_Z was not enabled so I added a check to see if SKEW_CORRECTION_FOR_Z was enabled

#if ENABLED(SKEW_CORRECTION)
  #if !defined(XY_SKEW_FACTOR) && !(defined(XY_DIAG_AC) && defined(XY_DIAG_BD) && defined(XY_SIDE_AD))
    #error "SKEW_CORRECTION requires XY_SKEW_FACTOR or XY_DIAG_AC, XY_DIAG_BD, XY_SIDE_AD."
  #endif
  #if ENABLED(SKEW_CORRECTION_FOR_Z)
    #if !defined(XZ_SKEW_FACTOR) && !(defined(XZ_DIAG_AC) && defined(XZ_DIAG_BD) && defined(XZ_SIDE_AD))
      #error "SKEW_CORRECTION requires XZ_SKEW_FACTOR or XZ_DIAG_AC, XZ_DIAG_BD, XZ_SIDE_AD."
    #endif
    #if !defined(YZ_SKEW_FACTOR) && !(defined(YZ_DIAG_AC) && defined(YZ_DIAG_BD) && defined(YZ_SIDE_AD))
      #error "SKEW_CORRECTION requires YZ_SKEW_FACTOR or YZ_DIAG_AC, YZ_DIAG_BD, YZ_SIDE_AD."
  #endif
  #endif
#endif

I can see why git is so useful, managing code updates like this would be a major pain in the a$$!

Best!

@thinkyhead
Copy link
Member

crosses initialization

Thanks @Lonczakt — I was looking for the new version of that error. I'll patch it shortly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants