Skip to content

[BUG] G29 results in random small Z error with BILINEAR leveling #23843

@tombrazier

Description

@tombrazier

Did you test the latest bugfix-2.0.x code?

Yes, and the problem still exists.

Bug Description

At the end of running G29, leveling is applied to current_position. See line 880 of Marlin/src/gcode/bedlevel/abl/G29.cpp

current_position.z -= fade_scaling_factor * bilinear_z_offset(current_position);

When bilinear_z_offset() is called, cached values from the previous mesh are used to calculate the offset. The freshly measured mesh is ignored.

In principle, it might seem like this should not happen because earlier in G29, on line 443, there is:

 if (!no_action) set_bed_leveling_enabled(false);

And set_bed_leveling_enabled() has this:

    #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
      // Force bilinear_z_offset to re-calculate next time
      const xyz_pos_t reset { -9999.999, -9999.999, 0 };
      (void)bilinear_z_offset(reset);
    #endif

However, there are two problems with this way of clearing the cached Z offset values. First, set_bed_leveling_enabled() goes on to call planner.apply_leveling() which calls bilinear_z_offset() again. This is only really a problem if you call G29 when the nozzle is already at the last probing point, e.g. by calling G29 twice in a row.

Second, and more seriously, calling bilinear_z_offset() caches not only the specific nozzle position but the whole mesh cell in which that nozzle position falls (in variable lastg). So there are many scenarios where G29 can use the wrong cached values for some time.

Example behaviour with the default values in Configuration.h:
GRID_MAX_POINTS_Y = GRID_MAX_POINTS_X = 3
Bed size is 200 x 200.
PROBING_MARGIN = 10

Valid mesh already exists and leveling is applied.

G0 X150 Y150   # this in the same mesh cell as the last probing point
G29            # X150 Y150 gets cached after X-9999.99 Y-9999.99, and current_position ends up wrong
G0 X150 Y150   # this is still in the same cell, so the old mesh values are still being used
G0 X101 Y101   # this is still in the same cell, so the old mesh values are still being used
G0 X50 Y50     # finally the new mesh is used
G0 X150 Y150   # the new mesh is used

Bug Timeline

In 2017, commit 830851d.

Expected behavior

No response

Actual behavior

No response

Steps to Reproduce

No response

Version of Marlin Firmware

Latest bugfix branch

Printer model

No response

Electronics

No response

Add-ons

No response

Bed Leveling

No response

Your Slicer

No response

Host Software

No response

Additional information & file uploads

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions