Bed leveling faulty_region weird behavior / possible bug

Basic Information:

Printer Model: Custom Tevo Black Widow
MCU / Printerboard: BTT SKR3
Frontend : Mainsail

Describe your issue:

I’m experiencing a weird behavior with bed mesh leveling. I get a substituted point that should not be substituted.

I issue this command :

BED_MESH_CALIBRATE mesh_min=140,95 mesh_max=185,129

and in my config.cfg :

[bed_mesh]
faulty_region_1_min: -50, 0
faulty_region_1_max: 30, 45

(it’s a clamp at the border of the bed near which I cannot probe. Useful when I have objects placed near the border of the bed, which is not the case most of the time)

I expect no faulty point with this particular mesh leveling request, but I get :

11:26 PM : 0 (140.00, 95.00), substituted points: [(0.0, 0.0), (0.0, 45.0), (30.0, 0.0)]

11:26 PM bed_mesh: faulty region points

I’ve track down the algorithm in extras/bed_mesh.py, but I didn’t managed to reproduce the error extracting the _generate_points method. (klipper/bed_mesh.py at 645a1b8364c3110f706db0f976ac5fa20b968c36 · Klipper3d/klipper · GitHub)

I don’t know if this might be related to my bl_touch config :

[bltouch]
x_offset : 30
y_offset : -16

I’m not familiar with kipper internals, and I’m unsure how the probe offset is integrated in the above.

I don’t know how to debug it further. I’ve check that I do have the latest version of klipper, reboot the raspi, etc… I don’t understand why the _generate_points method, run separately with the same parameters doesn’t yield any substituted points, while in the “real situation” I get this one weird substitution.

Any help would be greatly appreciated.


for the sake of completeness, what I mean by “run separately with the same parameters” is a python file like this :

def _generate_points(self, error):
    # This is copied from source code

class Obj:
    pass

self = Obj()

self.mesh_min = 140, 95
self.mesh_max = 185, 129
self.radius = None
self.faulty_regions = [((-50, 0), (30, 45))]
self.substituted_indices = collections.OrderedDict()

self.mesh_config = {
    "mesh_min": (0, 0),
    "mesh_max": (325, 225),
    "x_count": 3,
    "y_count": 3,
}

_generate_points(self, RuntimeError)

print(self.points)
print()
print(self.substituted_indices)

Have you checked Bed Mesh - Klipper documentation?
In particular:

  • Faulty regions are given as probe coordinates and not nozzle coordinates
  • Are replaced by points at the border of the faulty region

Hello.

Thank you very much for answering.
Yes, sure, I checked Klipper documentation. (Which is among the best I have every seen in an opensource project, it’s remarkable)

And yes, I indeed saw that faulty region is given as probe coordinates.

But the point that is substituted is 140, 95 which makes 110, 111 given my probe offset.
An neither of theses are anywhere close to be within the faulty region (-50,0), (30, 45)

But as I said, since I was not able to reproduce the behavior with the core algorithm, it means that (probably), either the faulty region or the tool coords “arrive” in the _generate_points modified.

For all I know, the fronted could be messing with my command, my command might be malformed. Or it’s some bug in klipper.

But again, not sure how to debug further. What I would need is to add a bunch of print statement in the klipper code but I don’t quite get where klippy would output them. Debugging page did not help really helped in that regard.

I’m not really sure that I understand what you are reporting:

You are starting your mesh at 140,95, which corresponds to point 0: PM : 0 (140.00, 95.00) and [(0.0, 0.0), (0.0, 45.0), (30.0, 0.0)] looks like the definition of your faulty_region but WRT your bed. Makes no sense to exclude points that are not on your bed.

Ok, I think I understand the confusion, sorry for that.

I’ll try to give the relevant context…

[stepper_x]
position_min:-38
position_max: 325
position_endstop: -35

@x = -35, extruder is off bed, but this allows the probe to still reach the area.

The faulty region correspond to a clamp on the border of the bed. I have (-50,0), (30,45) but could as well be (0,0), (30,45) I tested it, and it result in the same behaviour.

Now BED_MESH_CALIBRATE mesh_min=140,95 mesh_max=185,129 is actually part of my PRINT_START macro for a given part. I use the bounding_box given by the slicer, so that I probe only the relevant part of the bed. This is nicer than probing the full bed for a small piece in the middle.

So if I start to print a huge piece, my slicer would issue : BED_MESH_CALIBRATE mesh_min=0,0 mesh_max=325,235. In that case, the faulty region becomes relevant.

In other words, the faulty region is definitely on the bed, but might or might not be in the calibrated mesh region.

Now, [(0.0, 0.0), (0.0, 45.0), (30.0, 0.0)] looks like a reasonable set of 3 point to substitute to a point that would be, let’s say, at 25, 5. But not 140, 95, which is outside the faulty region.

Here is some (not at scale) drawing :

So p0 is substituted by s0/s1/s2. Why would you do so ? This doesn’t seem logical at all.

Or do I get it all sideways ? Maybe I’m trying to do something that was not meant to be, but it feels like it would be quite natural for it to work that way (but maybe it’s just me)

Thank you very much for trying to help out. It’s very appreciated.

  1. I’m not sure if this interpretation is correct. I would guess this is just an information that due to the faulty_region definition a certain area is “hard-coded” as faulty regardless of the current mesh
  2. I’m also not sure if faulty_region was ever designed to work with an adaptive mesh

In any case, just spitballing here. Guess @Arksine could shed some light into this.