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

Mesh leveling and endstops #2830

Closed
dmelcer9 opened this issue Dec 6, 2015 · 35 comments
Closed

Mesh leveling and endstops #2830

dmelcer9 opened this issue Dec 6, 2015 · 35 comments

Comments

@dmelcer9
Copy link

dmelcer9 commented Dec 6, 2015

I suppose that this is partially my fault, but...
My z-endstop is mounted at the MAX position, and to test mesh leveling out, I enabled it and gave it dummy values. When I sent the command to move the x-axis, the z-axis rose, and ignored the z-endstop, crushing the endstop until it shorted. When mesh leveling is enabled, it should check the z endstops to make sure it doesn't go out of range.

@epatel99
Copy link
Contributor

epatel99 commented Dec 6, 2015

Hi, sorry to hear about the crash and it shorted.

I am not sure what happened. Just moving the x-axis before probing and enabling the mesh feature shouldn't change the z-axis. If you put values inside the mesh for testing I suggest putting very small values as the values are added as offsets when feeding them to the planner.

In planner.cpp

    if (mbl.active) z += mbl.get_z(x, y);

Maybe they even should be negative as you have your z-endstop at the MAX position (so it won't pass the endstop). I have number of printer but none configured as that, and am not sure how that should work. Yeah, no delta either but might get one someday.

I wrote a thing for the mesh based feature. But it was moved somewhere else by someone else.
https://github.com/MarlinFirmware/MarlinDev/blob/9a093b2e8f/Documentation/MeshBedLeveling.md

I also made a little progress with automating the probing, though very simplified.
http://www.thingiverse.com/thing:1120142

@Roxy-3D
Copy link
Member

Roxy-3D commented Dec 6, 2015

@epatel99 You are aware that the mesh bed leveling idea was evolved and got used in the Delta Auto Bed Leveling, right? There are some things I want to change on it, but it does probe a grid without manual effort now.

One of the things I want to change is probing of the entire probable area instead of just the intersection of printable and probable. And this is a ways out, but I think it should be possible to save a very detailed mesh for the Delta and then do a 3 or 4 point adjustment of the saved mesh.

@epatel99
Copy link
Contributor

epatel99 commented Dec 6, 2015

@Roxy-3DPrintBoard No I was not aware of that. I have tried to look at all issues that mention mesh levelling. When you say "Now" which repo and branch are you thinking of? I wish I could help more but the project is just a mess I think.

@dmelcer9
Copy link
Author

dmelcer9 commented Dec 6, 2015

I would like to revise the original issue to say that no matter what values the mesh leveling is set to (I tested this time with a variance of +/- 1mm), when the endstops are at only at the max value, the z-axis moves up when you move any of the axis, ignoring the endstops. It seems that the endstops have to be at the min value for mesh leveling to work properly.

@Roxy-3D
Copy link
Member

Roxy-3D commented Dec 6, 2015

@epatel99 I haven't looked at the full history. But I bought a low end Delta kit from Geeetech. (Don't ever buy anything from Geeetech!!!) The Marlin they had on the controller board was one of the first ones that had Auto Bed Leveling. It was super old, so I started bringing up RC-2 on it.

RC-2 has the concept of the Mesh leveling (that you brought to Marlin???). Except, for Delta's it automatically probes the bed. The bad news is it only probes the intersection of probable and printable. It would seem to me that should be changed. But I don't have enough experience using it yet to know if that is the 'right' thing to do.

When you say "Now" which repo and branch are you thinking of? I wish I could help more but the project is just a mess I think.

We are working hard to get the code base cleaned up. Just pitch in where you can. But please take a look at the Delta Auto Bed Leveling in RC-2 (and now RC-3). It seems that the same code could be used to build the mesh for Cartesian printers too.

@epatel99
Copy link
Contributor

epatel99 commented Dec 6, 2015

@Roxy-3DPrintBoard Will check. But, please note that the old Auto levelling is using a tilted plane for correction and has a probing feature called GRID, that I have seen there be a lot of problem with. This is not at all the same as MESH. Meshed is a net based correction that will do a bilinear calculation within a probed square.

Here is the first pull request for it where I tried to explain the rational behind it
#1619

@Roxy-3D
Copy link
Member

Roxy-3D commented Dec 6, 2015

Yes, I understand! The reason the tilted plane does not work well for Delta's is because they tend to have a bowl or dish shape to the coordinate system. So a non-linear mesh is needed to correct. And in fact, if you dig into it a little bit, the Delta's can only do a circle shape. After the points are measured, it will go fill in the un-probed corners with some what reasonable values.

@Wackerbarth
Copy link
Contributor

I'll chime in here with some observations:

  1. We don't really have BED LEVELING -- I have seen a printer that did. It had cams that would unlock and lock the spring-loaded bed supports while using the nozzle to push the bed to the desired height.
    What we do have is BED TILT COMPENSATION. It assumes that the effective bed height is a linear function of X and Y position of the nozzle. (A sloped plane)

Note that the problem may not actually be with the bed itself, but with the mechanism which moves the nozzle.

There are presently two ways to determine the parameters for the height adjustment equation.
In an ideal world, probing the height of 3 points is adequate.
You can also oversample the heights and perform a least squares fit.
This is currently controlled by the AUTO_BED_LEVELING_GRID option.
That sampling is currently done on a rectangular grid which is truncated for a circular bed.

Edward has done a different kind of compensation which we might call MESH COMPENSATION.
That compensation relies on a stored mesh of heights and rather than using a simple formula to compute the desired height correction, performs an interpolation in its stored table.

@epatel99 -- A question for you: Have you considered using a triangular mesh instead of a rectangular one? I can visualize a nice regular array of (nearly?) equilateral triangles covering either a circular or rectangular bed fairly well.

@Roxy-3DPrintBoard brings up the issue of delta printers needing a "dished" compensation.
This is not because of a warpage in the bed itself, but primarily due to errors in the dimensions of the positioning system. If you are computing position based on an arm length that is in error, the result is that the nozzle is not actually where you think it should be.

Edward's mesh compensation has the advantage of not caring about the cause of the error. It just makes the correction that is experimentally correct.

Note that compensation can also be improved by using a better mathematical model of the mechanical system.
For example, correcting the arm lengths will help "flatten" the dish effect on delta movements.

If the apparent warpage is hyperbolic in nature, adding a quadratic term to the correction can compensate for that. I suspect that many of the problems of this nature (for non-delta mechanisms) are due to misalignment of (supposedly) parallel supports (or cantilevered support without adequate rigidity)

I do want to raise an additional question about the entire probing protocol.
Presently, the procedure adjusts the probe so that it contacts the bed at the assumed location for the reading. If the positioning mechanism is accurate, and the error is actually due to irregularities in the bed, this is the proper way to take the reading.
However, if the bed is actually flat, and the irregularities are due to the positioning mechanism, this is the wrong way to take a reading. (Think errors in the delta's positioning, for example).

If the bed is actually flat, any error in a reading is just the product of the horizontal offset of the probe and the actual slope of the bed. But, this is a (very small) CONSTANT.

I contend that we should position the mechanism based on the nozzle rather than the location of the probe. We will get readings which are more consistent with the corrections needed while printing.

@epatel99
Copy link
Contributor

epatel99 commented Dec 6, 2015

@Wackerbarth Yes I am fully aware of the bad name of it all. But as the programmer I am I think it is better to be consequent than add confusion, which made me use the name LEVELING as the previous method was using. I don't mind the LEVELING part of the name as long as it is easy to understand what it helps with and how to use it.

Yes I have also thought about doing a triangular mesh, but I can picture it being way more complex and prone to bugs. The movements should still be straight lines/linear and all lines has to be split over the mesh boundaries. Keeping the boundaries on straight x/y lines makes that part easy, otherwise the calculations need more complex line by line crossings, and triangle vertexes would have 6 edges and small lines close to triangle vertexes could be cut in many crazy small segments. So, considering all that I just use this simple straight lines, and it works good for me. When using it it feels like mesh squares around 10 to 15 cm in size is good enough. The rigidbot big build plate is 29x39 cm.

@Wackerbarth
Copy link
Contributor

I make the statement about leveling to really point out that we are doing only TILT compensation.
There are a significant number of users who seem to think that that compensation should correct for twisted or dished errors. As we know, it doesn't.

As for the triangles, for arbitrary triangles, you might have a concern.

However, if you form the triangles on a rectangular grid, they are not really different from the rectangular case. Even with rectangles, you can have a line that passes near a vertex and clips off a very small corner of one rectangle. One advantage of triangles is that they are planar. A rectangle is, in general, not.
How do you interpolate within the rectangle?

@KiteLab
Copy link
Contributor

KiteLab commented Dec 6, 2015

@Wackerbarth
Have you ever really looked up how the z-level-compensation for deltas works?
Please compare adjust_delta() in Marlin_Main.cpp with
get_z() in mesh_bed_leveling.h.
Any idea why they both use an array of probed points and interpolate in a square if them?

@epatel99
Copy link
Contributor

epatel99 commented Dec 6, 2015

@KiteLab Interesting, didn't know that about delta. Though, I don't see that any line splitting is done. I think it can be a bit dangerous not doing any line splitting. Say the printer is about to output a long line from A to B but in-between them the bed is curved up, i.e. A is at z 3 B is also at z 3 but in-between the bed vill be at z 3.5...with splitted mesh boundaries a movement z 3 -> z 3.5 -> z 3 is possible. Without its dangerous that the hotend might run into something that might have been built at z 3.5

update: ok think I got it now...it happens in prepare_move_delta. But not over the boundaries but rather uniform segments/second like.

@KiteLab
Copy link
Contributor

KiteLab commented Dec 6, 2015

@epatel
The delta moves are already splittet to very short segments #define DELTA_SEGMENTS_PER_SECOND 200 in prepare_move_delta()

@epatel99
Copy link
Contributor

epatel99 commented Dec 6, 2015

@Wackerbarth Yes, the GRID probing threw me off track in the beginning wasting quite a few hours before understanding that the model is just a tilted plane. That's why I ultimately ended up adding the MESH thing.

For the non-planar way I still believe that lines need to be segmented. The delta way doing it uniformly might be good enough. But I think doing it on triangle boundaries is still way more complex than straight x/y boundaries. Also what I meant with the trip vertexes is that at a rect edge you will at most have 2 cuts and for tri vertexes you can have 3 cuts.

Within a rect I use a bi-linear interpolation, which seem to work fine.

I don't think one should have crazy warped beds and super wide mesh tiles/squares. The area within a square should be fairly even, and for my almost crazy warped bed about 10 cm per side per square seem to be fine.

@Wackerbarth
Copy link
Contributor

@epatel99 -- I think that there is a lot of confusion in this, and other, areas because the names of the selectors do not do a good job of reflecting what it is that they truly represent.

Perhaps we could describe them as THREE_POINT and MULTI_POINT sampling procedures for the TILT_CORRECTION and use MESH_CORRECTION (which should be available for both Cartesian and Delta kinematics) to describe the interpolated correction method. I also wonder why we have two different implementations of essentially the same algorithm.

I consider AUTOMATIC to be somewhat separate because it is also possible to manually determine correction terms and enter those factors into a compensation state vector.

The "warped" beds that I have seen are actually the result of the mechanical misalignment of two actuators that should, but do not, move in perfectly parallel lines.

@Wackerbarth
Copy link
Contributor

@epatel99 = "a rect edge you will at most have 2 cuts and for tri vertexes you can have 3 cuts."

I don't follow you here. If I have a rectangular mesh, I can cross many rectangles in moving all the way across the bed.

If I have ANY convex boundary, I can have at most 2 intersections between that boundary and a straight line.

@epatel99
Copy link
Contributor

epatel99 commented Dec 6, 2015

@Wackerbarth in a tri mesh each vertex will have 6 edges and passing a line close to a vertex will almost certainly cross 3 of them, causing 2 small to tiny segments (and 3 cuts resulting in 4 segments).

@Wackerbarth
Copy link
Contributor

@epatel99 -- I wouldn't say "almost certainly". But I will agree that it is more likely. But, in doing so, you also remove the issue of interpolating within a warped rectangle which has its own source of error.

I also think that it is not unreasonable to place a threshold on the fragmentation and recombine segments that remain sufficiently collinear after the corrections are applied.

@epatel99
Copy link
Contributor

epatel99 commented Dec 6, 2015

@Wackerbarth I think bi-linear is good enough for me at the moment, and I am actually using this method on all my prints currently.

It's a balance between the warped bed and number of mesh points. I can't see it be exceptionally better than it is currently for me. Though what currently bugs me most is some artefact I think can be traced back to the stepper routines. Some day I might hook up a oscilloscope just to check, artefacts and vibration wise something fishy seems a fot.

This image explain the bi-linear calculation pretty good. (from http://www.dspguide.com/ch23/7.htm)

bi-lin

@KiteLab
Copy link
Contributor

KiteLab commented Dec 6, 2015

Are you talking about the same?
two_grids

@Wackerbarth
Copy link
Contributor

More, or less. But he is leaving out the slanted cuts across his "squares" and doing a bilinear interpolation instead.

The advantage of the triangles is that the interpolation is linear (but that is likely offset by having more potential boundaries) and the improved packing of the triangles when attempting to cover a round bed.

But, hopefully in the future we will be able to factor all of the Z-compensation into a module. That will provide a mechanism from which we could test various strategies without tearing into the rest of the code.

@dmelcer9
Copy link
Author

dmelcer9 commented Dec 7, 2015

OK, I narrowed the problem down a little. After hitting the endstop, on the first move, the printer travels up by whatever X1 Y1 is set to, regardless of endstops (just as it travels down past the endstop when the endstop is on Z-MIN I'm guessing). If X1Y1 is set to 0, the printer doesn't move like that. I might just have to move my z-stop to the bottom instead of fighting with the firmware.

@KiteLab
Copy link
Contributor

KiteLab commented Dec 8, 2015

@dmelcer9
Sorry for the somewhat theoretical discussion. Back to your problem.
Ok, so you have a z-max endstop and a probe?. Where is the probe connected, if you have one? To the Z-min-pin?
Additionally a link to your Configuration.h and Configuration_adv.h would be helpful to analyse this problem.
A little hint about your branch/version is always helpful - that makes comparing to our standard configurations much easier.
What does M119 say in mid air and when the probe (if you have one) is active.
Do you have a delta system?

@thinkyhead
Copy link
Member

Sorry this issue has languished for so long. I would definitely like to see this issue patched, if it isn't already. Can you confirm that this problem still exists in the RCBugFix branch? (At your convenience, of course!) If it does, we can use the logging feature to figure out where the logic is screwing up. I'm hopeful that this will be relatively simple to figure out.

@Roxy-3D
Copy link
Member

Roxy-3D commented Feb 23, 2016

@epatel99
And as a side issue... I'm trying hard to use all of the existing Mesh architecture. I do need to add a few functions and global variables to the class mesh_bed_leveling{} to handle what I'm doing for the Delta Mesh Bed Leveling.

The point I'm making is class mesh_bed_leveling{} is going to be important to Marlin going forward! And soon... The Cartesian version of Mesh Bed Leveling is going to have to play catch up to the Delta version! :) epatel99 is going to have to get busy to keep things at par.

@epatel
Copy link
Contributor

epatel commented Feb 23, 2016

@Roxy-3DPrintBoard Happy to hear you are doing progress on the mesh stuff. About keeping things at par we'll see if I can fit it in between kids and job etc. It's been a while since I even compiled Marlin. My current compilation works fine (a couple of glitches but manageable) and every time I try to compile the project it seems to have moved into an unrecognizable state for me (often too buggy too).

@Roxy-3D
Copy link
Member

Roxy-3D commented Feb 23, 2016

About keeping things at par we'll see if I can fit it in between kids and job etc.

@epatel Yeah, we all are busy! And I'm trying to do the new code with minimum changes to the existing Mesh Leveling. I'm doing that on purpose so anybody already familiar with the current Mesh Leveling can easily step up and keep things going. Somebody with a Cartesian machine will want the new features enough to pull it forward. It won't have to be you.

every time I try to compile the project it seems to have moved into an unrecognizable state for me (often too buggy too).

You aren't talking about the Release Candidate, are you? We have been trying hard to stabilize that.

@thinkyhead
Copy link
Member

every time I try to compile the project it seems to have moved into an unrecognizable state for me

@epatel Currently RCBugFix is our best bet to avoid the more obvious bugs. We try really, really hard not to commit anything there that hasn't been thoroughly vetted. And we commit obvious fixes there as quick as we can.

@dmelcer9
Copy link
Author

dmelcer9 commented Mar 2, 2016

@thinkyhead Sorry for not testing this; been quite busy recently. Hopefully I'll have time over the weekend.

@eberttbi
Copy link

@epatel99 Like the OP I've had some issues with mesh leveling and Z endstop too. I have two endstops per axis. On the Z axis I do my homing to z-max position. Therefore in Configuration.h the definition is "#define Z_HOME_DIR 1". That means that after "G28 Z" my Z-position = Z_MAX_POS. Now your mesh-leveling code assumes that all homing will have Z at 0 afterwards. I had to change several things in the firmware to get it right (for me). I'll list all changes here:

  1. Configuration.h: I added the definition #define MESH_START_SEQ "T0\nG28 X Y\nG1 X10 Y10 F5000\nG28 Z\nG1 Z4\nG29 S2" in section "#if ENABLED(MESH_BED_LEVELING)" to enqueue a custom Gcode sequence at MeshStart.
    Note: My printer is equipped with a dual extruder and everytime I do a homing run with active extruder T1 I get offsets.
  2. Marlin_main.cpp: I changed MeshStart as follows case MeshStart: mbl.reset(); probe_point = 0; enqueuecommands_P(PSTR(MESH_START_SEQ)); break;
    In the MeshNext section I modified the line current_position[Z_AXIS] = MESH_HOME_SEARCH_Z; to #if Z_HOME_DIR < 0 current_position[Z_AXIS] = MESH_HOME_SEARCH_Z; #else current_position[Z_AXIS] = Z_MAX_POS; #endif
    The same change was done in the routine gcode_G28().
  3. ultralcd.cpp: In static void lcd_level_bed() I changed the enqueue to enqueuecommands_P(PSTR(MESH_START_SEQ));

@epatel99
Copy link
Contributor

@eberttbi Great to hear you get it to work for your setup. Sorry that I haven't fixed all ways to use the mesh feature. As I only have "simple" machines, those are what I can test and I don't like to write code I can't test myself. Though, might look into buying a delta some day.

@eberttbi
Copy link

I have an important update to my post regarding the changes needed in the routine gcode_G28() in the Marlin_main.cpp! Since the mesh bed leveling concept overrides the coordinate of the z-axis right after a G28 command in the same way G92 Zxxx.xxx does, it is possible to crash your z-axis (to be exact the nozzle) into the bed or 'shoot through the roof'. The Marlin firmware accepts parameters for G28 commands, so you can run a homing for a single axis or maybe two. F.i. G28 Y would home the Y axis only. The standard implementation of mesh bed leveling would override the current Z position to MESH_HOME_SEARCH_Z, or with my modification to Z_MAX_POS if your homing direction is towards Z_MAX_POS, every time a G28 command is executed no matter what additional parameters were given. But your current Z position could be anywhere between 0 and Z_MAX_POS. To overcome that problem you could use the following code in Marlin_main.cpp. Replace your mesh bed leveling section in gcode_G28() with this code:

  // For manual leveling move back to 0,0
  #if ENABLED(MESH_BED_LEVELING)
    if (mbl_was_active) {
      if (homeX || homeY) {
        if (homeX) current_position[X_AXIS] = mbl.get_x(0); // only move x-axis if it was homed
        if (homeY) current_position[Y_AXIS] = mbl.get_y(0); // only move y-axis if it was homed
        set_destination_to_current();
        //feedrate = homing_feedrate[X_AXIS];
        feedrate = min(max_feedrate[X_AXIS], max_feedrate[Y_AXIS]) * 60;
        line_to_destination();
        st_synchronize();
      }
      if (homeZ) { // only set z-axis coordinate if it was homed
        #if Z_HOME_DIR < 0
          current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
        #else
          current_position[Z_AXIS] = Z_MAX_POS;
        #endif
      }
      sync_plan_position();
      mbl.active = 1;
      #if ENABLED(DEBUG_LEVELING_FEATURE)
        if (marlin_debug_flags & DEBUG_LEVELING) {
          print_xyz("mbl_was_active > current_position", current_position);
        }
      #endif
    }
  #endif

@thinkyhead
Copy link
Member

Sorry we didn't get this patch in before RC4. It needs a bit more feedback and testing. But if it holds up then we can submit it for the next RC, which we believe will be the last one – and the one we end up tagging 1.1.0.

@jbrazio
Copy link
Contributor

jbrazio commented Apr 28, 2016

Thank you for your interest making Marlin better and reporting this issue but this topic has been open for a long period of time without any further development. Marlin has been under heavy development for the past couple of months and moving to it's last mile to finish the RC cycle and release Marlin v1.1.0. We suggest you to try out the latest RCBugfix branch and reopening this issue if required.

@github-actions
Copy link

github-actions bot commented Apr 9, 2022

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked and limited conversation to collaborators Apr 9, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

9 participants