Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FR] Allow motion before homing (perhaps by implementing M211) #111

Closed
marcio-ao opened this issue Jan 8, 2018 · 22 comments
Closed

[FR] Allow motion before homing (perhaps by implementing M211) #111

marcio-ao opened this issue Jan 8, 2018 · 22 comments

Comments

@marcio-ao
Copy link
Contributor

Hello,

I have been experimenting with Klipper on a Lulzbot TAZ 6 printer and one issue I am running into is that I am unable to lift the head prior to homing. This is necessary on the TAZ in order to avoid hitting hardware on the print bed when homing X and Y. The TAZ homes by lifting the head 5mm in Z, then homing X and Y.

I understand the motivation of disallowing homing before G28 to protect the user, but there are legitimate reasons for needing to move Z before homing X and Y. One option might be to implement M211 (enable/disable software endstops) and to allow the start GCODE to disable software endstops -- in such cases, klipper could allow motion without homing.

This would provide safety for the user, while also allowing a workaround for cases in which it may be absolutely necessary to move prior to homing.

@marcio-ao
Copy link
Contributor Author

marcio-ao commented Jan 8, 2018

BTW, Marlin provides a Z_HOMING_HEIGHT option which causes the Z axis to be raised as part of G28, but I believe having the start GCODE do it via a M211/G0/G28 would be a superior option. There is no need to emulate the byzantine configuration choices in Marlin if it can be done with a sequence of GCODEs -- let's keep Klipper simple :)

One cool option may be to implement macros, as Redeem does, as this would allow users to build out complex instructions out of GCODE primitives.

@KevinOConnor
Copy link
Collaborator

KevinOConnor commented Jan 8, 2018 via email

@marcio-ao
Copy link
Contributor Author

Yes, there are tons of different ways to do things. Marlin, unfortunately, is too complex in trying to support so many options. I think it would be best to avoid that. For the TAZ, it always lifts the nozzle prior to homing. However, if the head is at the top, this triggers a Z_MAX endstop which protects the printer.

I would suggest you start by implementing "M211" (enable/disable software endstops), which would allow the start GCODE to raise Z before a "G28". I assume this would be a straightforward addition? Most of the special cases can be handled by start GCODE using G0, so long as there is a way to move the head prior to G28.

@marcio-ao
Copy link
Contributor Author

I think a homing_commands option in config would cover most cases as long as the recursion in G28 was avoided. All of the cases I can think of could be handled perfectly:

; (Option one) Lift head prior to homing:
M211 S0 ; Turn off software endstops
G0 Z5     ; Raise Z 5 mm
G28        ; Home all axis
M211 S1 ; Restore software endstops
; (Option two) Use a safe Z homing position:
M211 S0 ; Turn off software endstops
G28 X0 Y0 ; Home X and Y
G0 X10 Y150  ; Go to homing button
G28 Z0; Home Z
M211 S1 ; Restore software endstops
; (Option three) Raise Z first and use a safe homing position
M211 S0 ; Turn off software endstops
G0 Z5 ; Raise 5 mm
G28 X0 Y0 ; Home X and Y
G0 X10 Y150  ; Go to homing button
G28 Z0; Home Z
M211 S1 ; Restore software endstops
; (Option four) Raise Z first, home X next and finally Y.
M211 S0 ; Turn off software endstops
G0 Z5 ; Raise 5 mm
G28 X0; Home Y
G28 Y0 ; Home Y
G0 X10 Y150  ; Go to homing button
G28 Z0; Home Z
M211 S1 ; Restore software endstops
; (Option five) Deploy probe and use a safe homing position
M211 S0 ; Turn off software endstops
M401 ; deploy probe
G28 X0 Y0 ; Home X and Y
G0 X10 Y150  ; Go to homing position
G28 Z0; Home Z
M402  ; Stow probe
M211 S1 ; Restore software endstops
; (Option six) Deploy probe and use a safe homing position and preform an adjustment on Z
M211 S0 ; Turn off software endstops
M401 ; deploy probe
G28 X0 Y0 ; Home X and Y
G0 X10 Y150  ; Go to homing position
G28 Z0; Home Z
M402  ; Stow probe
M211 S1 ; Restore software endstops
G92 Z-1.5 ; Adjust Z after probing

...etc

@marcio-ao
Copy link
Contributor Author

@hg42: Would using M211 to allow motion before homing be a sufficient workaround? This is what I am proposing.

PS: Love your handle. We really need a G42, right? A GCODE that is the ultimate answer to all our 3D printing problems :)

@marcio-ao
Copy link
Contributor Author

Also, I think serious thought needs to be placed whether quirk-for-quirk compatibility with Marlin is desired. I would argue that the answer should be no. A lot of mistakes were made in Marlin and I think Klipper could be a much simpler FW if it did not strive for 100% GCODE compatibility. Personally, I would lean towards implementing complex behavior using sequences of simple GCODEs, rather than adding a bunch of complexity to G28 and G29 as Marlin does.

@KevinOConnor
Copy link
Collaborator

KevinOConnor commented Jan 8, 2018 via email

@jmgiacalone
Copy link

RepRapFirmware (used on the Duet) implements G28 (as well as other actions) by calling a macro. Such macros are defined for homeall, homex, homey etc. The macros contain lower level G-code to home the axes, for example, the Ormerod Y homing macro reads:

G91
G1 Z5 F200
G1 X20 F2000
G90
G92 Y0
G1 Y-250 F2000 S1
G92 Y0
G1 Y3 F200
G1 Y-30 F200 S1
G92 Y0
G91
G1 X-20 F2000
G1 Z-5 F200
G90

which covers most of the examples already discussed (lift Z, bounce Y).
The use of macros is in my opinion a nice feature of RepRapFirmware, and allows complex customisations without specific G-codes.

Alternatively, could the firmware not simply allow moves before homing, but issue a warning back to the user during those moves?

@marcio-ao
Copy link
Contributor Author

Again, I'm not sure what the best option is.

Heh. Use the following heuristic: If Marlin does it like "this," then you should do it like "that" :D

Although in all seriousness, I think a major reason a lot of people are looking for alternatives is because Marlin is way too complicated. I've had the misfortune of having to do maintenance in Marlin and here are some of things I suggest you keep in mind:

  • Do not use C macros nested twenty-levels deep. There are some cases in which macros are the best tool for the job, but Marlin takes it to an absurd extreme. Example:
    #define HOME_AXIS_X() home_axis(X_AXIS); /* For god sake, why? */
  • Keep GCODE commands simple and with a well defined action. It is perfectly acceptable to require the user to compose a sequence of GCODEs to do a complex action like G28 in their start GCODE.
  • Don't be afraid to break compatibility with existing GCODE. Just because Marlin does it one way, does not mean you should have to do it that way. Marlin has plenty of historical baggage baked into it, as does the GCODE conventions itself.
  • Make it easy for developers to compose custom GCODE commands by building upon other GCODE commands. In Marlin, you must touch a bunch of obscure state variables to get anything done and there does not seem to be an easy way to say "do what Gx does followed by what Gy does". I suggest every core GCODE should be a function, and it should be possible to extend Klipper with new GCODEs simply by calling existing GCODE functions.
  • Provide easy-to-use verbs in your code, like moveTo(x,y), or extrude(mm) so that contributors can use those to implement new GCODEs without necessarily understanding the internal state variables.

Unfortunately, Klipper wont catch a Z_MAX endstop event unless it is coded to. (Runtime endstop detection is not currently implemented.)

Ah, that makes sense. As far as I understand it, Klipper is working on pre-computed delays, I guess figuring out what to do if a move is interrupted is tricky. Yet, I think this is a pretty useful feature for homing, in particular. Perhaps G0 doesn't need to do it, but there needs to be at least a special type command that moves along one axis until and endstop is triggered. Perhaps this can be a special command like G0 that can be used in the start GCODE for homing purposes, or it could be an option to G0 that tells it to enable endstop checking.

My main fear with this approach is that we'd have to implement a bunch of synthetic g-code commands (like HOME_X_IF_X_NOT_ALREADY_HOMED) to make it work well

I don't think that level of complexity is needed. If someone calls G28 X0 and X is already homed, so be it. It doesn't take that much time to redo it and homing only happens once in a multi-hour print. No need to optimize the hell out of it to save a second or two.

@marcio-ao
Copy link
Contributor Author

Alternatively, could the firmware not simply allow moves before homing, but issue a warning back to the user during those moves?

@jmgiacalone : If Klipper goes down the macro route, then perhaps the safety-checks could be lifted for macros. This would mean that if a user typed "G0" without homing, Klipper would disallow it, but if a user added "G0" to a macro, then Kipper would allow it without homing (under the assumption that if someone is writing a macro, they know what they are doing).

@hg42
Copy link

hg42 commented Jan 8, 2018

We really need a G42, right? A GCODE that is the ultimate answer to all our 3D printing problems :)

at least we already have M42, but it doesn't answer everything yet :-)

@hg42
Copy link

hg42 commented Jan 8, 2018

@KevinOConnor I deleted my comment above, because I agree it's tone was harder than I intended.

@hg42
Copy link

hg42 commented Jan 8, 2018

the usual way is to restrict automatic movement like printing but allow manual moves. Someone pressing a button in the host gui should know what (s)he does.

There is probably no absolutely correct way to distinguish those.
Perhaps other firmware has already solved this problem.

You can also see this very simple and from a practical point of view:

  • usual slicer software always uses G28 in the start code.
  • if someone wants to move without, there must be a reason.
  • if someone changes the start code intentionally, (s)he should know why (and how). It's their own responsibility.

So, I don't see a problem with allowing moves without homing (and in fact have already implemented that, controlled by a setting). If someone wants the patch, just ask.

@KevinOConnor
Copy link
Collaborator

I've created a new test branch ( work-homing-override-20180116 ) that will allow one to define a series of g-code commands to run in place of G28 commands found in the normal input stream. It's activated by a new [homing_override] config section - see config/example-extras.cfg on the new branch for details.

I'd like to get feedback on this code.

git fetch ; git checkout origin/work-homing-override-20180116 ; sudo service klipper restart

@marcio-ao
Copy link
Contributor Author

@KevinOConnor: Can you clarify what is meant by "one per line". Would it look like:

[homing_override]
gcode: G0 Z10
gcode: G28 X0 Y0
gcode: G0 X10 Y250
gcode: G28 Z0

Or:

[homing_override]
gcode:
G0 Z10
G28 X0 Y0
G0 X10 Y250
G28 Z0

Also, can you add whitespace at the start of the gcodes and comments to the end?

-- Marcio

@marcio-ao
Copy link
Contributor Author

marcio-ao commented Jan 17, 2018

@KevinOConnor: I was able to answer my own question by trying it :) The following stanza in "lulzbot-taz6-2017.cfg" allows the printer to home correctly:

[homing_override]
gcode:
    G0  Z10              ; lift nozzle to clear bed hardware
    G28 X0 Y0            ; home X and Y
    G1  X-19 Y258        ; move to safe homing spot
    G28 Z0               ; home Z
    G0  Z10              ; clear homing button

Yay! Making progress!

Anyhow, I have one question. The endstops are not checked during G0 moves, is that correct? That means "G0 Z10" could be dangerous if the Z axis is near the top of the printer (near Z_MAX endstop). Is there anyway to do a safe move? Perhaps a special flag to G0 to enable endstop checking? Alternatively, maybe this could be enabled by default inside "homing_override" since those moves are presumed to take place before homed?

@marcio-ao
Copy link
Contributor Author

Here's another hair-brained idea. Maybe G28 could be overloaded to support special moves with endstop checking. Here is what I am thinking:

G28 Z0   ; Do a normal home on Z using the default homing direction and move until the endstop is hit.
G28 Z10  ; Home in the positive Z direction for a maximum of 10 mm, stop if Z_MAX endstop is hit
G28 Z-10 ; Home in the negative Z direction for a maximum of 10 mm, stop if Z_MIN endstop is hit

Since the normal G28 is generally only used with a zero value, this change would be backwards compatible with Marlin and other slicers. This would allow a nozzle raise to be written in homing_override as such:

[homing_override]
gcode:
    G28  Z10             ; lift nozzle to clear bed hardware (safely)
    G28 X0 Y0            ; home X and Y
    G1  X-19 Y258        ; move to safe homing spot
    G28 Z0               ; home Z normally
    G0  Z10              ; clear homing button

@KevinOConnor
Copy link
Collaborator

KevinOConnor commented Jan 17, 2018 via email

@marcio-ao
Copy link
Contributor Author

@KevinOConnor: There are a couple reasons we home to the bottom. One thing is speed, the Z is screw driven and it takes quite a while to do the entire travel. We also use an electrical contact probe, so pushing a homing button has the side effect of squishing some of the molten filament off the nozzle, which can help with subsequent probing (we also run the nozzle through a wiper pad a few times for the same reason). For our newer model, which is Z belt driven, we are considering homing to the top.

As for the GCODE additions, I don't think there will be as many as you think. There is a lot of variance on how homing is performed, but it can mostly be described in terms of simple motions. There is an even greater variance in the probing sequence, but once again, I think that with a fairly short GCODE vocabulary it could be done with macros. The way Marlin does it, with hundreds of configuration options, is pretty confusing, but I understand they are constrained by RAM and would not necessarily be able to implement a run-time macro library.

This was referenced Jan 25, 2018
@KevinOConnor
Copy link
Collaborator

I've merged the homing override code into the master branch. I understand there is a desire to be able to do a "move with endstop probing", but I think we should probably track that separately from this item.

@wizhippo
Copy link
Contributor

wizhippo commented Feb 1, 2018

Is MOVE_WITH_ENDSTOP_CHECK coming?

@KevinOConnor
Copy link
Collaborator

KevinOConnor commented Feb 2, 2018 via email

@github-actions github-actions bot locked and limited conversation to collaborators Dec 24, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants