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.04k stars 19.15k forks source link

Auto Bed ad Mesh leveling offsets and plane equation 'd' #3840

Closed boelle closed 8 years ago

boelle commented 8 years ago

From @RalphSutherland on May 10, 2016 8:13

HI, I'm working on improving auto-bed leveling, and may add auto mesh bed leveling too. But I, like others apparently, have been confused by the probe offsets notation in the code, which isn't helped by what I think is an inconsistent documentation and resulting inconsistent code.

Two of the offsets look like nozzle-probe offsets and one like a probe-nozzle offset. I'd like to change that and the documentation.

Here are my notes form my codebase. I want to make use of the 'd' coefficient in the plane equation to make the rotation transform/inverse transform take into account the mean bed height as well. A composite z-probe+bedheight offeset could be used now as long as I reverse some of the signs, but I'd like to make the system consistent and work with systems where home is off bed and below and 'd' is not small. Any comments welcome, and if/when I get working code I'll pull request to the appropriate branch.

  // Offsets to the Z probe relative to the nozzle tip.
  // X and Y offsets must be integers.
  #define X_PROBE_OFFSET_FROM_EXTRUDER  50   // nozzle X to Z probe offset: probe is  -left  +right
  #define Y_PROBE_OFFSET_FROM_EXTRUDER  20   // nozzle Y to Z probe offset: probe is -front +behind
  #define Z_PROBE_OFFSET_FROM_EXTRUDER -1.0  // nozzle Z to probe Z offset: probe is -below  +above
  //
  // There is inconsistent useage of z offsets throughout the code and documentation for unknown
  // reasons.  Here, if the nozzle tip is still +1mm above the bed when the probe triggers, then
  // the probe should -1mm below the nozzle, not +1mm as given in the documentation example,
  // to be consistent with the other offsets. The code is written so that the inconsistent useage in the 
  // documentation *seems* to work.
  //
  // Basicly the first two were being treated as nozzle -> probe offsets and the last
  // as a probe -> nozzle offset.  No wonder it has been confusing for people.
  //
  // If z_raw is the coordinates above home (0.0) according to the planner unadjusted,
  // then if the z probe triggers at z_p = z_raw = +2.5mm above home,  and z_probe_off = -1mm
  // (below) wrt the nozzle, then the nozzle is at z_noz =  z_p - z_probe_off = 2.5 - -1 = +3.5mm.
  // ie z_probe_off = -1.0mm, or *-z_probe_off* for the nozzle = +1mm off the bed
  // when the probe triggers.  eg2 probe is offset -1.0mm below the nozzle, not the other
  // way around!!
  //
  // In different code locations the offsets are applied inconsistently,
  // using + when - of a negative offset is more consistent.
  // Using a -ve offset makes including it in  the more general
  // rotation transformation more consistent.
  //
  // Note: If the home is below the bed, the probe must be disabled during homing so it doesn't
  // trip an 'endstop' early. If the home is above the bed, then the home needs to be disabled in hardware
  // and software, so just the probe works.
  //
  // If home and the probe are the same mechanism, then the bed zero will be at the corner homed at
  // and some of the bed may be negative, but hopefully <z_p> ~ 0.0, or not too large, and 'd' is small
  // and has been neglected up to now.
  //
  // In more detail:
  //
  // To get a G0 Z0 to put the nozzle on the bed we to ask the planner to move to
  // r_raw = z_p + z_probe_off = 2.5 + -1.0 =  2.5 - 1.0 = +1.5mm.  [again the probe must be
  // also disabled in hardware or software to let this happen.]
  //
  // After an auto leveling grid least squares fit, the last coefficient 'd' *is* 
  // the mean bed height above home, as measured by the z-probe, 
  // and is assumed to be accurate ie call it d = <z_p>.  Currently it is discarded which is a pity.
  //
  // On systems with home = bed = 0 this will give d = <z_p> ~0.0, and this seems to be why it has been
  // ignored so far.  But in a system with an off bed home below the bed [ so that even with a bed tilt
  // the z-min endstop wont trigger even accidently, d > 0.0 ],  d = <z_p> then is a nicely *measured* z value
  // that *should* be used in a general bed calibration.
  //
  // Making the plane equation coefficients global, means both main (G29, G0 etc) the
  // planner can access the rotation *and* the z_d value, and along with the z_probe_off be
  // used to put the nozzle relably on the plate for the difficult first layer.
  //
  // Bed height = 'd' = <z_p>, so nozzle location above the bed, z_noz, is z_raw - d - z_probe_off
  // eg to get nozzle on bed, 
  //
  // z_noz = z_raw - d - z_off = 1.5 - 2.5 - -1.5 = 0.0;  // - and -
  //
  // and     
  // 
  // z_raw =  z_noz + d + z_off = 0.0 + 2.5 - 1.0  = 1.5mm  ;// + and +
  //
  // in this way the forward and reverse transforms use the same sign conventions within each direction.
  //
  // finally:
  // if the sign of z_probe_off is made this way with same signs as d in the transforms,
  //  then dz = d + z_probe_off can be used in a plane equation *for the nozzle* 
  // instead of d for the probe, and the transforms are just
  //  z_raw =  z_noz + dz  and z_noz = z_raw - dz
  // 
  // which is what I am implementing in a global nozzle plane equation

Copied from original issue: MarlinFirmware/MarlinDev#420

boelle commented 8 years ago

From @RalphSutherland on May 10, 2016 11:33

Basically I now take the measured z probe points, offset immediately to the nozzle height, and feed those nozzle points through the plane and rotation equation solvers, and in planner set and get I transform from nozzle coordinated to stepper coordinates, and back again including the rotation in the nozzle plane, and the plane equation coefficient[2] z offset, which is now in terms of the nozzle, not the z probe.

boelle commented 8 years ago

From @jbrazio on May 10, 2016 13:55

When probing the nozzle shifts the "center of attention" to the probe, so all measurements must be related to the probe. When sifting back *_PROBE_OFFSET_FROM_EXTRUDER are applied to correct to the new "center of attention" which is the nozzle.

For instance, when you define probing points all of them are subject to the probe being the "center of attention", not the nozzle.

boelle commented 8 years ago

From @gddeen on May 10, 2016 17:5

A good thing would be to remove the Z-Probe from the Auto Bed Leveling and also make it part of Mesh Bed Leveling.

When I issue M401 M402 with Mesh Bed level, it is as if the Z-Probe isn't exist...

boelle commented 8 years ago

From @RalphSutherland on May 11, 2016 0:27

Yes I agree. Mesh Bed Leveling and Auto Bed leveling have a lot in common, and could be made 1) more uniformly treated, and 2) mutually compatible. I like how MBL can be temporarily disabled and then restored, and I like how ABL does the automatic measuring - each can take advantage of the other using a unified transform and inverse transform approach to mapping nozzle coordinates to stepper coordinates.

I also now realise that the earlier coders do indeed intend the z-probe odffset to be -ve (logical) but the current documentation and wiki give worked example where it tells you to use +ve offsets, which is crazy.

boelle commented 8 years ago

From @RalphSutherland on May 11, 2016 0:30

We need to make the target and source coordinates clear in the code. Stepper coordinate as defined by the homing. Probe-Bed coords defined by the probe. and Nozzle coordinates which is what the G-Code expects to use.

boelle commented 8 years ago

From @Roxy-3DPrintBoard on May 11, 2016 2:7

I like how MBL can be temporarily disabled and then restored, and I like how ABL does the automatic measuring - each can take advantage of the other using a unified transform and inverse transform approach to mapping nozzle coordinates to stepper coordinates.

I'm going the opposite approach. I'm going to do a high resolution mesh, and then allow either 3-Point or Grid Auto Leveling on the Mesh.

boelle commented 8 years ago

From @gddeen on May 11, 2016 2:23

@RalphSutherland, I think people just under comment and use nouns as verbs and such in short phrases which are parseable 3 to 4 different ways. If you play with it long enough you get a lot of 'Eureka' moments where you actually see what 'bed somewhere below but above 0' means... Is bed a verb or noun? Below what? above 0. Ahhhhh a positive value.

The average person will follow what someone else told them to do with the values...

boelle commented 8 years ago

From @Blue-Marlin on May 11, 2016 2:27

In every case, if 3-point-, grid-, delta- or mesh-leveling we have to probe a set of points. What we do with the measurements is an other thing. Sadly at the moment the format and order of the measurements is 'optimised' for the different uses. That has to be cleaned up.

boelle commented 8 years ago

From @Blue-Marlin on May 11, 2016 2:39

In almost all cases the trigger point of a probe is below the nozzle (z-zero). Only in a few cases, when the nozzle has to be pushed up (or the bed down), like with FSRs or the proposed TILT_PROBE, the trigger point is above z-zero.

boelle commented 8 years ago

From @Sniffle on May 11, 2016 2:58

Dont forget the metal sensing(name escapes me) and ir probes those are also positive

boelle commented 8 years ago

From @Blue-Marlin on May 11, 2016 9:26

@Sniffle No, they are not! The bottom of an inductive, capacitive, ir probe is above the nozzle, but their trigger points are below.

boelle commented 8 years ago

From @thinkyhead on May 12, 2016 1:47

To put it succinctly:

Z_PROBE_OFFSET_FROM_EXTRUDER

The documentation on these options is not ambiguous.

// nozzle Z to Z probe offset: probe is -below  +above (the nozzle tip)

When you trigger a probe below the nozzle, the current Nozzle Z is larger than the current Probe Z, measuring from the bed upwards. So probe_z - nozzle_z == negative_value. Let's say you are probing and when the probe triggers, the Z position (of the nozzle tip) is 2mm. The nozzle is 2mm above the bed. Where is the probe "tip" located? We now know it's at current_position[Z_AXIS] + (Z_PROBE_OFFSET_FROM_EXTRUDER). The Z_PROBE_OFFSET_FROM_EXTRUDER in this case should be -2.

Compare the documentation for Z_PROBE_OFFSET_FROM_EXTRUDER to that for X:

// nozzle X to Z probe offset: probe is  -left  +right

When the probe is to the left of the nozzle, then the Nozzle X is larger than the Probe X. So probe_x - nozzle_x == negative_value.

These offsets are applied to determine where to put the nozzle when you want a certain probe position. To put the probe at X=20, for example, with X_PROBE_OFFSET_FROM_EXTRUDER set to -10 (left of the nozzle), you want to put the nozzle at X=30. Hence:

nozzle_x = desired_probe_x - (X_PROBE_OFFSET_FROM_EXTRUDER); // e.g., 30 = 20 - (-10)
jbrazio commented 8 years ago

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[bot] commented 2 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.