Marlin icon indicating copy to clipboard operation
Marlin copied to clipboard

Universal Z offset setting

Open selalipop opened this issue 4 years ago • 16 comments

Requirements

  • This is a WIP
  • Allows using a single unified interface and set of GCode for defining Z offset, regardless of leveling method in use.
  • Should be reflected in real-time while printing for live adjustments
  • Should be saved in EEPROM (currently saved with existing Planner fields)

Description

Currently implemented as Babystepping with matching adjustment to M209 offsets (home_offsets)

Benefits

Creates a single interface for users that is live adjustable and saveable. Currently Z offset implementations for certain bed leveling systems have inconsistent characteristics in relation to those two requirements

Related Issues

Resolves https://github.com/MarlinFirmware/Marlin/issues/18986

selalipop avatar Aug 10 '20 20:08 selalipop

It looks like this resets every time I run bed leveling with Bilinear Leveling enabled, as in the value is saved, but I need to add more of a Z offstep each print

I tried applying the offset after retrieving the Bed Leveling algorithms Z offset, but it doesn't to help. That makes me wonder if somehow the mesh is having the Z offset add to it's values, will look into more

selalipop avatar Aug 11 '20 07:08 selalipop

  • Marlin already has offsets —set by G92— which are applied to every move. Why wouldn't you just use the existing G92 Z to adjust the current position and shift the nozzle?

  • MESH_BED_LEVELING already contains a single Z offset which is applied to every move while leveling is enabled.

  • It was considered to have a global Z offset for other forms of leveling, but this adds unnecessary overhead to every move and is redundant to babystepping, G92 Z, M851 Z, and the other methods that are available to adjust the position without incurring added overhead during printing.

I need to add more of a Z offstep each print

You'll need to do some trials to figure out why. Printing from a file simply runs multiple G-code commands in a row. If you can reproduce the shift in Z position with a few G-code commands instead of running a whole print, that would be a better way to isolate the problem. Slicers add a lot of extra commands to the file, and after a print is done the state of the machine is unknown. If you print a G-code file that only contains "M117 Hello World!" do you also see the shift in Z position? What if you add G1 X100? Does that make the Z position shift? Do you only see the problem if you print an object over 4mm tall? These are the kinds of tests that should be done to determine the source of the issue.

thinkyhead avatar Aug 11 '20 20:08 thinkyhead

If I may make a suggestion, a useful addition would be to add an option to G92 that allows changing the Z offset without knowing what the current Z position is. For example, I currently have the following in my start gcode for PETG:

G0 Z2
G92 Z1.90

to adjust the offset by 0.10 mm. But it would be nice to be able to just say

G92 A0.10

(A is just the letter I picked, for (A)djust - if you have any better ideas let me know). This would just adjust Z by that amount and would make start gcode cleaner.

ManuelMcLure avatar Aug 11 '20 21:08 ManuelMcLure

Let me know if you think this would be a good addition and I'll see about generating a PR.

ManuelMcLure avatar Aug 11 '20 21:08 ManuelMcLure

Actually, I think a better implementation would be to add R as an option that makes the X, Y, Z and E values following into relative adjustments. So

G92 R Z-0.10

would adjust Z by -0.10.

ManuelMcLure avatar Aug 11 '20 22:08 ManuelMcLure

~~Another option would be to use G92.3 as "adjust by this relative offset".~~ Never mind - G92.3 is already defined in CNC gcode as "resume offsets suspended with G92.2" so we'd need to use something like G92.4. Probably better to add the R option instead.

ManuelMcLure avatar Aug 11 '20 23:08 ManuelMcLure

Marlin already has offsets —set by G92— which are applied to every move. Why wouldn't you just use the existing G92 Z to adjust the current position and shift the nozzle?

Didn't think of taking advantage of the G92 offsets on the firmware side if there's already some kind of offset stored, but the idea is there are currently multiple ways to set a Z offset, but having the combination of live editing (especially on the printer), and saving and restoring that value, and having it work independently of a specific bed system is the issue.

It was considered to have a global Z offset for other forms of leveling, but this adds unnecessary overhead to every move and is redundant to babystepping, G92 Z, M851 Z, and the other methods that are available to adjust the position without incurring added overhead during printing.

I think the problem is exactly that though, the combination of multiple features and interfaces for the concept of a Z offset causes a lot of confusion. The goal is to have one way


That being said, I can see a tweak to this idea that's a little less intrusive, gets rid of any print-time overhead, and doesn't introduce a totally new concept if the worry is adding to the already overloaded term Z offset and that is to just saving and restoring babysteps

Right now Babystepping Z Probe emulates this by concurrently modifying the Z Probe offset, but like I mentioned in the feature request, it's easy to have it go out of sync, and more importantly, it only works if you're using a method that uses Probe offsets.

Most of the work is already there with babysteps being able to save a cumulative value based on configuration, this would just be a command that reapplies the last set of babysteps stored to EEPROM. I'd also have a define similar to the M420 one that applies the saved total after each G28.

I want to emphasise the goal isn't to create something that can't be done other ways, but rather, to expose a singular method of doing a common task: dialing in a Z offset which will stay mostly constant for future prints.


Actually with the babystepping approach, the offsets could just be saved with M206, so it'd be mostly a UI/Configuration change, allowing what Babystep Z Probe Offset does for M851, but for M206, which works regardless of bed leveling selected

selalipop avatar Aug 12 '20 01:08 selalipop

Just pushed a rewrite that would address the concerns noted by using M209 offsets

Ends up being very similar to Babystepping M851 option, but there were enough differences to justify a separate LCD function

Biggest benefit over M851 babystepping is support regardless of which method was chosen for bed leveling. Additionally, this method respects updates made via G-code while on the edit screen, which is useful for large adjustments

Remaining work is mostly around ergonomics. Need to add a few messages and a name. "Live Z adjustment" is a name I saw come up a lot when looking into the various Z offset methods that currently exist due to the similar Prusa feature

Since this can be changed with G-code I think having it use small steps and rely on the Babystepping multiplier works

selalipop avatar Aug 12 '20 19:08 selalipop

I like the idea generally, mostly because it's optional, plus MESH_BED_LEVELING already has a Z offset, and a global Z offset can be useful for unobtrusive but persistent adjustment of the print height.

Speaking of M.B.L. … This new universal Z offset needs to replace the mbl.z_offset. That way when ENABLE_UNIVERSAL_Z_OFFSET is turned off it will also affect Mesh Bed Leveling. And then the command G29 S4 Z<offset> in mbl/G29.cpp should be changed so that it sets this new offset.

thinkyhead avatar Aug 13 '20 06:08 thinkyhead

Now we have to ensure that whenever this new offset is changed while leveling is enabled, it correctly modifies the current_position.z. We also do this whenever a mesh value or the Z fade value is changed. This is because all of these offsets are applied transparently at the planner level.

Note that the final effect of this will probably make it incompatible with babystepping. This is one of the catch-22s about Z offsets that are applied to motion at the planner level. Since the offset is applied to the position while leveling is enabled, babystepping can't be combined with Z offset editing.

This is because whenever the value is edited while leveling is enabled, since the nozzle isn't moving in that instant, the logical current_position.z must also be shifted to account for the new offset. This ensures that the translation between stepper step counts and logical millimeters matches up both ways.

If the value is edited outside of babystepping, you might still expect the nozzle to move up and down. While it will cause a change in the nozzle's Z height, it only occurs at the destination points of each line, so the movement doesn't end up being regular or predictable unless the lines are very finely divided, and no Z movement occurs when the machine is idle.

thinkyhead avatar Aug 13 '20 08:08 thinkyhead

I added a method called center_z_base_offset which is called after G29 is done to automatically try to minimize the amount of Z leveling adjustment during motion / printing. In relation to the Z Fade, this will minimize the weird deflections that come from too much Z adjustment.

This change removes the need for the user to adjust the global/base Z offset for the mesh, and the value could actually remain hidden if we discover it works well. We'll have to see whether there are any good use-cases for setting or adjusting it manually.

This new Z offset is not exactly suitable for use as a babystepping substitute, and we already have both a Z Home Offset and a Z Workspace Offset, so those have the global Z adjustment pretty well covered. The mesh base Z offset is different from those only in that it is invisible to the coordinate system so it affects only low level motion while leveling is enabled. In that sense it is also a good idea to keep the value small, so enabling and disabling leveling doesn't cause too much of an immediate shift in Z.

If this is now functioning well and doesn't show any weird behaviors in testing then it can be merged very soon. Please give it a test run at your earliest convenience!

thinkyhead avatar Dec 07 '22 22:12 thinkyhead

Universal Z height setting using duplication mode. I guess this should go here or it will be flagged as already open. We use 3 heads printing all at the same time in the newly fixed Duplication mode.

  1. We have a fixed unadjustable Z endstop. (Ref point screw)
  2. We don’t use any probes. All manual tramming of three points.
  3. We don’t use G29 or any bed leveling method or mesh.
  4. M206 allows us to change the Z offset. We need a method to transfer babystep on the fly settings to M206. (Or at the end of a “first layer test” which we do for quality control when it starts to look sloppy or too thin) When we run a print and the first layer needs adjusting due to room temp or filament mismatches using temperature, we need to use babysteps and then save them through the LCD to EEPROM replacing M206 Z + or -00.000. This then becomes the universal offset for just that machine. Is this possible?

SlickNickeL avatar Feb 17 '23 19:02 SlickNickeL

Universal Z height setting

Workspace offsets are applied with G92 and this is the most straightforward offset.

The M206 offset is applied relative to the home position, and it is an open question whether this offset should be applied as part of the workspace offset (as now), or if it should only be applied at the end of G28 (as with Marlin 1.x). With the legacy behavior a call to M206 had no effect on the current position, and only took effect on the next G28. This was changed so that a call to M206 after G28 would modify the current position in the same manner as G92.

There is hopefully no need for an additional "global z offset" outside of G92, as this would only add yet more calculation overhead to every move. A "hidden" Z offset that applies at the steps level but doesn't get reflected in the logical position has been suggested in the past.

The concept applied in this PR is only meant to modify the behavior of mesh leveling, so that the Z fade applies minimally, and does not end up propagating some large base Z offset.

The general issue with babystepping is that it immediately moves the Z axis, so additionally applying those babysteps to a global Z offset or mesh base Z offset would double the actual distance moved. Or, if the babysteps were not applied to the Z axis in real-time, but only to a global Z offset, you would not see the babysteps occur until later, the next time a move is done. In early versions of Marlin, babystepping was only permitted during moves, so that the Z motion would occur relatively soon in combination with other moves, and it was considered to be an element of dialing-in the first layer.

thinkyhead avatar Feb 18 '23 09:02 thinkyhead

This makes sense. Here is a new dilemma to consider on Z offsets. Marlin now has an effective Duplication mode that can be improved for manufacturing using 3 printheads and up.We have been using Repetier for several years now using 3 printheads at one time, but my opinion has always been that Marlin can do it better because of a more common sense approach and KISS. Manufacturing printers are the exact opposite of consumer units when it comes to bells and whistles. Most restraints are because of the physics.3 head printers can’t use a mesh or auto level system at all. Just a tramming of 3 points and fixing the Z optical endstop. Using Marlin, M206 is then used to fine tune the first layer. This process of tweaking M206 for 1st layer at .15 takes a long time and careful attention because M206 positive values brings bed and nozzle closer to each other. 3 print head’s crashing into ALCA-5 tool plate aluminum is a disaster. (We use a precision 10mm SS polished block along with our own tramming program so all heads move well above print bed when making adjustments.)Even though high quality parts are used in the printers, temperature changes from seasonal conditions, AC to Heating on shop floor WILL change the Z Offset enough to affect 1st layer quality.  M206 is not going to be a solution. Too much time and holding a Surface Pro and making adjustments doesn't work. There is no other way to correctly adjust the Z offset (no probes or mesh) on the LCD. There needs to be a KISS method from the LCD. Here is a solution that Repetier uses and is effective for manufacturing printers. I like this and it has worked well. Repetier has a menu for bed coatings. I believe it works like you have pointed out with M206. Several selections are available for selection, Blue Tape, .05mm surfaces, glass and a few others. THEN they have a custom setting. THIS IS AWESOME, user can enter a number negative or positive in very fine increments +- 0.000 up to 2 mm in either direction AND can violate the physical Z endstop. (This is why we use optical endstops because they can easily be violated past their -0- simply by using a longer blade.) once the value is entered be it the -0.xxx or 0.xxx enter is selected, Print head does an immediate G28 and the new value is registered. This would be in line with M206. It’s important for this negative number to go beyond Z endstop 0.0. Ideally the Z-endstop and print bed surface should be initially set at +1 or 2 mm between them. THEN fine tuned DOWN to the actual Z 0.0.   Important note: Our machines all home off of the print bed towards the back with no possibility of a cold print head with boogers attached to make bed contact. Any movement made always required a Z+10mm lift. I believe Repetier menu is for changing only M206 Z +-0.000 and not the X or Y. Also Marlins current M206 Z 0.00 would better serve our purpose as Z0.000. It would be no problem for the value entered to be x.xxx places and stored as x.xx as long as the fine tuning is applied, it doesn’t matter what would show in M206. Also in Repetier, the custom setting always shows what was set, so when it is selected and viewed, the current known adjustment is displayed either a -0.xxx or a +0.xxx value, cumulative from the last time it was accessed (value pulled from the stored M206 Z 0.xxx)Repetier uses this bed coating option even on single printhead printers.  It’s an effective way to add glass, blue tape or what ever type of coating and only have to change the bed coating from the menu.  (This is truly a universal Z offset be it only +-2mm on Z axis.) It does do a G28 after any selection, comes back online and is ready with the new settings saved automatically in EEPROM. All other mesh and autolevel features are unaffected.  I have read where the Z offset can be effected by the new additional material thickness, but that is on the user of hall-sensors. We have a machine waiting and ready using Marlin, if you need to test something like this. Our goal is to switch over to all Marlin.  Thank you for your response.

SlickNickeL avatar Feb 18 '23 17:02 SlickNickeL

I'm wrong on some of the above M206 for Repetier. I ASSUMED It used M206 but that is not the case. It looks to be Z Offset in code and saved to EEPROM. Bed coatings also are a cumulative process to any of the other Z probe functions. It does function as a universal Z offset.

SlickNickeL avatar Feb 20 '23 22:02 SlickNickeL