MarlinFirmware / Marlin

Marlin is an optimized firmware for RepRap 3D printers based on the Arduino platform. Many commercial 3D printers come with Marlin installed. Check with your vendor if you need source code for your specific machine.
https://marlinfw.org
GNU General Public License v3.0
16.26k stars 19.23k forks source link

[FR] extend valid range for z probe #7268

Closed agrif closed 7 years ago

agrif commented 7 years ago

In Conditionals_post.h, line 809-813:

// Boundaries for probing based on set limits
#define MIN_PROBE_X (max(X_MIN_POS, X_MIN_POS + X_PROBE_OFFSET_FROM_EXTRUDER))
#define MAX_PROBE_X (min(X_MAX_POS, X_MAX_POS + X_PROBE_OFFSET_FROM_EXTRUDER))
#define MIN_PROBE_Y (max(Y_MIN_POS, Y_MIN_POS + Y_PROBE_OFFSET_FROM_EXTRUDER))
#define MAX_PROBE_Y (min(Y_MAX_POS, Y_MAX_POS + Y_PROBE_OFFSET_FROM_EXTRUDER))

Why are the probe positions limited to MIN_POS to MAX_POS? In my setup, my probe is located fairly far to the right of the extruder, and so the probe can access X positions higher than X_MAX_POS, but when I use these values in my autolevel setup, the compile fails due to these defines.

Is there a reason these values are defined to be so restrictive? Would it be better to have:

// Boundaries for probing based on set limits
#define MIN_PROBE_X (X_MIN_POS + X_PROBE_OFFSET_FROM_EXTRUDER)
#define MAX_PROBE_X (X_MAX_POS + X_PROBE_OFFSET_FROM_EXTRUDER)
#define MIN_PROBE_Y (Y_MIN_POS + Y_PROBE_OFFSET_FROM_EXTRUDER)
#define MAX_PROBE_Y (Y_MAX_POS + Y_PROBE_OFFSET_FROM_EXTRUDER)
Bob-the-Kuhn commented 7 years ago

Agreed, if there are X and/or Y offsets then the probe can reach areas the nozzle can't. If the nozzle can't reach a position then probing that position is of no value.

The purpose of these defines is not very clear. Marlin needs to know what NOZZLE positions the PROBE can reach.

All the mesh/grid arrays are populated with Z compensation values for when the NOZZLE is at those locations. In order to get those values Marlin has to position the PROBE at those locations.

agrif commented 7 years ago

My search earlier tells me it's used for:

Meanwhile position_is_reachable_by_probe_raw_xy is only used if USE_NOZZLE_AS_REFERENCE is defined as true, which it is not, apparently. So it looks like it's only used for static compile-time checks.

I've modified my firmware to use the second code block in my post with no problems for a few prints. If you would like, I can whip up a PR against bugfix-1.1.x and we can move there. Or, not, if it's never worthwhile to probe those positions. I was doing it for symmetry's sake, and relying on interpolation to do its job.

fiveangle commented 7 years ago

[misread]

fiveangle commented 7 years ago

Actually I misread a bit of the above.

So your thought is to probe outside of the printable area and allow interpolation ? Is there a scenario where this would ever be better than probing the point directly ?

agrif commented 7 years ago

I don't know, I'm new to this whole thing. Interpolation happens anyway within the probed points, and interpolation will always lead to some error. My reasoning was that symmetrically-placed probe points would lead to more symmetric errors, and if you have to have error, it might as well be symmetric.

But in my case, symmetrically-placed probe points means probing outside the range accessible by the nozzle. And I suppose it bothers me a bit that valid configurations are discarded at compile time, whether or not they are useful. 😄

fiveangle commented 7 years ago

I think that's the issue: the premise that symmetry is more important/critical than direct measurement. I doubt you will find many who agree with this premise. Unless you have empirical data to support the notion…

agrif commented 7 years ago

Direct measurement is useful when printing near the probe points, but everywhere else it interpolates. A bad choice of probe points can lead to a very bad representation of the true bed surface. Laziest example: probing only the four corners of a bed with a dip in the middle.

Moving the right edge of my probe area closer to the print area would be nice, but that also moves all the points inside the probe area, because Marlin figures out probe points by subdividing symmetrically. I would much rather move my right side out of the printing area a little to get a probe point on the center of the bed where I know it is lowest, than move my left side further in to the printing area and incur an extrapolation cost there.

Basically: I want to trade an accurate direct measurement on the edges for a more accurate direct measurement in the center.

If I could give Marlin an arbitrary list of probe positions to use instead, that would be better, but I don't see a way to do this. This is a cheaper change.

agrif commented 7 years ago

Another reason why you might want to do this that I thought of: If you know you have a very flat bed, and use one of the bed leveling methods that assumes a very flat bed, then increasing the area of the probed region can only make the bed model better: the farther away the points are, the larger the z distance is, and the less likely that this distance falls within the measurement accuracy of the probe.

In this situation it would be advantageous to be able to probe outside the print area.

fiveangle commented 7 years ago

That would only be true in practice if your probe repeatability were << than your bed flatness. At the small theta angles we're talking, you pretty much have to probe the same distance outside your bed as between your on-bed probes (2x your printable width from 0,0 in a 0-origin cartesian) in order to reduce probe theoretical error just 50%. And this is assuming you have a "perfectly flat bed".

The reality is that with the majority of sensors in use today have repeatabiliity far >> than bed flatness, so assuming bed flatness being more critical than direct measurement is where I think many would challenge (myself included).

Even MIC6 cast aluminium sheet specifies +/-0.381mm flatness for 1/4"-5/8" thick sheet (which is on my Printrbot, and I can assure you is not perfectly flat, even over just the small 150mm square bed). Most sensors on the other hand appear very reliable, typically much better than +/-0.010mm.

Lastly, if your bed is known "absolutely flat" then why are you not using 3-point leveling ? ;)

If I could give Marlin an arbitrary list of probe positions to use instead, that would be better, but I don't see a way to do this.

Huh ? @Roxy-3D - is this true that users cannot specify any probe points with UBL ? Workflow posted here suggests otherwise.

G29 P2 B T    ; Do manual probing of unprobed points. Requires LCD.
...
G29 P4 T      ; Move nozzle to 'bad' areas and fine tune the values if needed
              ; Repeat G26 and G29 P4 T  commands as needed.
agrif commented 7 years ago

Lastly, if your bed is known "absolutely flat" then why are you not using 3-point leveling ? ;)

I'm sorry, that was what I meant. And in that case, you would want the points of the triangle as far apart as possible. Quarter-inch thick floatglass claims +/- 0.10mm, and is hardly a specialty material.

The only thing I'm trying to argue here is that probing outside the printable area is a reasonable thing to want to try, and probably shouldn't be a compile time error.

fiveangle commented 7 years ago

The only thing I'm trying to argue here is that probing outside the printable area is a reasonable thing to want to try

I absolutely agree, and if you modify those entries in Conditionals_post.h to remove the *_PROBE_OFFSET_FROM_EXTRUDER offsets, you can do that at your leasure, with all the caveats that come with doing so. Using 3-point levelling is the only usage model that I think could be considered borderline valid (since yes, the farther appart the points are, theoretically the more accurate the plane vector detection).

and probably shouldn't be a compile time error.

Here's where we disagree. Which is fine - not everyone has the same take on user experience design. I compromise more on the side of what do I beleive will cause the least frustration and prevent the most usability failures for the maximum number of people, without causing unusable frustration for the expert or savvy user — but not everyone else thinks this way, or sometimes the normative belief of where that point resides can't be agreed on. I'm sure if you ask a dozen other people you'll get a dozen other answers :)

One solution for you, while still keeping less savvy users corralled from doom, would be to add a define for something like RELAX_PROBE_REACH_LIMITS and then put a conditional in the conditionals_post.h for it and if set, remove the probe offset values from the probe limit calcs above. But then you have even more configuration bloat for a feature with the number of users I can probably count on one hand. And while at it, I'm sure at least a few of those half-dozen users would want to relaxy only one axis, so then you'd need one for each X and Y. It gets a bit unwieldy at some point.

Regardless, if you want this, that's how I would do it. Fire off a PR and see if Scott agrees, then sit back and enjoy the pride that comes from contributing to open source 😁

fiveangle commented 7 years ago

Curious, how far out is your probe compared to your bed size ? I'm trying to think if it would make sense to try and detect blatantly odd configurations, and then automatically relax the conditional without any user interaction, if say probe offset was greater than a large percentage of the bed. But that would still be somewhat of a non-deterministic hack. The configuration is probably the only 100% safe way as is.

@agrif - what do you think about Scott's suggestions about bed size and probe limits here: https://github.com/MarlinFirmware/Marlin/pull/7228#issuecomment-312934976

Does your scenario not fit that model ?

agrif commented 7 years ago

I absolutely agree, and if you modify those entries in Conditionals_post.h to remove the *_PROBE_OFFSET_FROM_EXTRUDER offsets, you can do that at your leasure, with all the caveats that come with doing so.

I'm confused: it would be keeping the probe offsets in place, but rather removing the MIN/MAX that keep the calculated bounds within the area reachable by the nozzle. You seem to think this is unsafe sometimes, and that's why I'm confused. If the nozzle can safely reach X_MAX_POS, then surely the probe can safely reach X_MAX_POS + X_PROBE_OFFSET_FROM_EXTRUDER? I... can't see how this fails.

Using 3-point levelling is the only usage model that I think could be considered borderline valid [...]

In general, by not probing outside the print area you are throwing away information. If you have a probe point right on the edge, then this doesn't matter (unless you use catmull-rom, in which case the points outside the bed can give you curvature information...). And if you have probe points inset from the edge (which you should to reduce error on the more commonly used parts of the print surface) then probing outside the print area lets you interpolate on the edges, not extrapolate.

I don't think this is an edge case at all, and I feel like I'm not communicating why very well.

But then you have even more configuration bloat for a feature with the number of users I can probably count on one hand.

I agree this would be a bit silly. Either it's changed for everyone, or I content myself with maintaining a branch with these changes. I might give a PR a shot anyway.

Curious, how far out is your probe compared to your bed size?

My bed is 200mm by 200mm, and my probe is 47mm from my nozzle. I can only move my nozzle to 178mm on the X axis before the probe hits a support, but note that this means the probe can reach well off the side of the bed (225mm).

@agrif - what do you think about Scott's suggestions about bed size and probe limits here: #7228 (comment)

My bed is a little bit bigger than my movement limits. Which is probably weird, and something I will fix eventually, but I'm stuck with it for now. And to quote:

Note also that there are legitimate cases where you want to have your probing grid points set up symmetrically on the bed even though some of them cannot be reached and probed. The un-probed points can be filled in by extrapolating from the nearby probed points.

In my case, they can be both reached and probed, and Marlin didn't let me! 😄

agrif commented 7 years ago

Oh. Oh! I just realized why you linked #7228. The original code that's causing me issues was probably written this way because it uses X_MAX_POS and friends to stand in as approximate bed size, to prevent probing positions off the bed and possible damage.

In a glorious future where BED_X_MAX etc. are defined, then I would propose this fix:

#define MIN_PROBE_X (max(BED_X_MIN, X_MIN_POS + X_PROBE_OFFSET_FROM_EXTRUDER))
#define MAX_PROBE_X (min(BED_X_MAX, X_MAX_POS + X_PROBE_OFFSET_FROM_EXTRUDER))
#define MIN_PROBE_Y (max(BED_Y_MIN, Y_MIN_POS + Y_PROBE_OFFSET_FROM_EXTRUDER))
#define MAX_PROBE_Y (min(BED_Y_MAX, Y_MAX_POS + Y_PROBE_OFFSET_FROM_EXTRUDER))

That is, let the probe move anywhere it physically can, as long as the probe remains above the bed. It could be a happier solution for everybody involved. What do you think?

fiveangle commented 7 years ago

You got it.

With bed dims defined (yes more config bloat, but I think it's worth it in this case) we can then validly implement auto setting of the probe offsets for the masses by default to be limited to exactly as they are now within the printable area, as I had hoped to do in #7228 (but couldn't because the bed size wasn't known and so it couldn't cover every single case).

If we do as Scott suggested and define the actual bed size, then my conditionals can be implemented correctly in conditionals_post.h for every case, and have them over ridden by manual probe points in configuration.h (which are there now) which also solves your problem, because then you can actually manually set the probe area beyond the bed limits and Marlin wouldn't complain.

Solved for both the masses and for you.

agrif commented 7 years ago

Fantastic! I'll close this issue now then, and keep an eye on any forthcoming bed-size related changes. I'd be glad to help, but this sounds like it'll need deeper knowledge of Marlin than I have right now.

Thanks for putting up with my strangeness! I think this was very helpful.

fiveangle commented 7 years ago

I'm a bit miffed at myself, because I thought this was related to #7228 initially and wrote a post indicating so, but then removed my comment because I thought I misunderstood [dooh !]

I don't know if anyone is working on the work Scott suggested as he suggested I implement it, but I've gotten very busy at work so only really have time for now to respond to the issue tracker from my phone when i'm laying in bed unable to sleep ;)

If you want to tackle the implementation, I can help out, but I just don't have the time ATM to do the full implementation. You may be waiting for some time otherwise.

agrif commented 7 years ago

I mean to learn more about the source, so that might be a good motivator. And if somebody else gets it done before I do anything, well, at least I learned something in the process. Thanks again!

fiveangle commented 7 years ago

It actually should be quite simple to do, but I just don't anticipate getting more than 10/20 minutes here and there for a while. I'd definitely give it a shot if I were you, and feel free to ping me if you run into any things that don't make sense.

fiveangle commented 7 years ago

@agrif please see #7341

github-actions[bot] commented 3 years ago

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.