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

Axis movement without homing #335

Closed
ich777 opened this issue May 11, 2018 · 46 comments
Closed

Axis movement without homing #335

ich777 opened this issue May 11, 2018 · 46 comments

Comments

@ich777
Copy link

ich777 commented May 11, 2018

Is it possible to move the axis without homing the printer or an override?
Nothing found in the configuration folder.

If a print is finished i tell my printer to go to the back left position but if i want to higher the Z axis it's not possible, is there anything that i'm missing?
Even if the steppers turn off i can't move the axes any more.

@HorseEars
Copy link

@ich777
Copy link
Author

ich777 commented May 14, 2018

@HorseEars Thank you for that, but is there an implementation or option to turn that off? This would be a nice feature (there are enough ways to crash your axis without that option :D ).

@HorseEars
Copy link

I generally agree with you and would like to see an option for this because you can crash either way, especially on my dual carriage. It's possible to go into the source and disable the checks if you want.

@ich777
Copy link
Author

ich777 commented May 14, 2018

I think a simple configuration in the printer.cfg would be the best solution.
My coding skills are not the best and i think this would be a nice option to have.

@hg42
Copy link

hg42 commented May 14, 2018

Kevin didn't like that...so we didn't even try to create a pull request.

@ich777:

there are enough ways to crash your axis without that option

I agree...

There are some aspects:

  • after powering the printer the position is not known (though I tend to always move it to the same position before poweroff, but there are edge cases)
  • after disabling motors the position can change (I think this is usually correct, but depends on the printer construction)
  • I think there is a difference between automatic movment (e.g. gcode file) and manual movement (you should know what you are doing), but I don't see how the firmware could distinguish these two situations safely.
  • several printers need manual intervention before starting an automatic homing procedure at least in edge cases. Not being able to manually move makes rescue from bad situations more difficult. So it's one safety reason against another.

That said, @cruwaller has code for the simple setting to disable the safety "feature". I also have an implementation, but am using cruwaller's now.

There are two cases to consider:

  1. moving before homing
  2. moving after motor off

Both are separately configurable for cruwallers code.

@oderwat
Copy link
Contributor

oderwat commented May 24, 2018

I think something like this should work:

G92 Z0
G91
G1 Z7 F300
M114
G28 X0 Y0
G90
G1 Y180 F6000

Basically: I'd say if you G92 a position the printer should assume that it is in this position and allow movement.

@KevinOConnor
Copy link
Collaborator

I don't have much to add to this issue outside of that which is in the FAQ cited above. I've accidentally crashed my head into the bed/wall too many times - it's very frustrating. So, I think some simple software checks against obviously bad commands are worthwhile. To me, this isn't about protecting users from themselves; it's more about basic sanity checks.

I've no objection if someone wants to add a feature to move the printer without homing. (Indeed it's on the Todo list.) I've never gotten a pull request with that feature. Note, though, this is not as easy as disabling the check_moves() method, as some kinematics require check_moves() to operate correctly.

Separately, sometimes it is necessary to move the steppers for testing purposes. I recently added a STEPPER_BUZZ command to facilitate this (commit ee4f37f).

-Kevin

@hg42
Copy link

hg42 commented May 25, 2018

I've no objection if someone wants to add a feature to move the printer without homing

oh, really? I always had the impression you wouldn't accept it (I think we had discussions about it).

I am already trying if I can switch back to your repo.
I always wanted this, but there are some things, I need/want which you didn't accept, and that were discussed in some PRs and issues, apart from the tmc2130 and lpc176x etc. which are on the way now.
You didn't explicitely reject all of them, but kind of implicitly.
So, there is hope for me...

If I get around my current problems with switching back and real life gets out of my way, I already plan to reimplement some of these features:
allow_moves_before_homing
motor_off_does_not_invalidate_position (with enough friction, axes don't move by themselves)
retract_after_homing (to free the end stops)
homing_slowdown (allow to configure the speed of the second move, 1/2 is not enough for me)

@oderwat
Copy link
Contributor

oderwat commented May 25, 2018

I may try to implement a force homing with offesets as extension to the G28 command:

`G28 X0 Y50 Z5 O1' may then "think" the printer homed and is at X0 Y50 Z5 without doing any movement from the actual position.

I actually only want to move Z up relative and never more down than it went up. So I could also allow Z up without homing but always set Z0 to the last position automatically.

Something in those lines.

@oderwat
Copy link
Contributor

oderwat commented May 25, 2018

@KevinOConnor I destroyed beds, nozzles, linear rods and printing surfaces while testing my BLTouch and other sensor modifications for the Anet A8 / Marlin. In the end I created a Z axis decoupling so it physically could not move into the bed with much force anymore. I also modified my current printer with a separating Z coupler. I think that is just what happens when you are experimenting with and developing firmware or hardware.

I still understand your point of view but to me it is part of a safety procedure that I can lift Z by some mm anytime even if not homed!

@KevinOConnor
Copy link
Collaborator

KevinOConnor commented May 25, 2018 via email

@KevinOConnor
Copy link
Collaborator

KevinOConnor commented May 25, 2018 via email

@hg42
Copy link

hg42 commented Jun 6, 2018

@KevinOConnor Oh, I missed a post of you

In contrast, for example, a new klippy/extras/i_really_want_to_move.py that adds a new "I_REALLY_WANT_TO_MOVE" command which calls toolhead.get_kin().set_position(pos, homing_axes=...) ; toolhead.move()..

ok, I already know your preferences, but I don't agree with everything (though I can understand and accept your reasons).
The solution above makes sense and I admit I wouldn't have thought of this possibility. I would have created a pull request with a setting to enable the movement. But this is also because I have different goals.

Nobody (excluding experts) manually enters movement commands.
Out there is a whole world of tools that simply don't expect this restriction.
If you can only move the toolhead with a special command, every host software with arrow buttons etc. doesn't work out of the box (before homing) and must be changed in code or configured. I guess most hosts don't allow configuring another command for G0 or G1.

But, I think the real problem is another one.
I hope you agree...if someone moves the tool head manually (with buttons), he/she knows why and usually obeys the physical conditions (limits etc.).
The protection makes sense when printing automatically, and even more if the print is started remotely.

So the main problem would be to distinguish between manual and automatic movement.
This is not possible by looking at the gcode. The commands are basically the same.
Perhaps the speed of incoming gcode commands could give a hint.

But, on the other hand, which slicer produces gcode without a home command?
Which other cases need this kind of protection?

Additionally, I think it is often dangerous for the printer hardware to issue a home command, because after a failure everything can be wrong. And that's the main case where you have to move the toolhead before homing. Who protects the home command from doing bad things? E.g. if my printer's toolhead is beneath and below the bed it cannot home directly. The only one who can solve this is the user, so why should we restrict him/her?

@oderwat
Copy link
Contributor

oderwat commented Jun 6, 2018

The thing with the dangerous "G28" came to my mind too. I still think the limitation is artificial and not needed. May idea is to tell the printer "enable your motors and register that you are at the given position" it should just allow this and take an internal state being at that position. After this you can move it. Of course the user could make a failure. But he can do that also through other manipulations. Having a way a manual positioning, avoiding using the end stops seems like a reasonable wish to me.

@hg42
Copy link

hg42 commented Jun 6, 2018

The movement is prohibited by setting the limits to an impossible range (min = 1, max = -1) when the kinematics object is created and after motor_off:

self.limits = [(1.0, -1.0)] * 3

So there could be a command (like ALLOW_MOVEMENT_WITHOUT_HOMING) to set these to (min = -(position_max-position_min), max = +(position_max-position_min)), assuming the toolhead initially is at (0, 0), so it can move a full width in both directions.

Unfortunately there are hosts that do not allow the definition of custom buttons.

--

It is impossible to override arbitrary code by a module. You can usually only override parts that are designed to allow this.
So, most behavior implemented in the code base cannot be changed by a module (or extension, plugin).

That's why I once started an issue to discuss about an infrastructure for plugins. But at that time @KevinOConnor didn't like the idea.
Now we have "extras" as a mechanism to extend the code base. That's fine, but there are still a lot of things we cannot do in such an extra module.

--

One possibility to override certain code is to define hooks or handlers. A registration system could allow multiple modules to chain their manipulations.
This allows to intercept behavior, but the possibilities are restricted to functionality that is explicitly designed for interception (= providing hooks).

--

The natural way in object oriented software would be to create a derived class and use this instead of the base class.
For example, a new kinematics class CoreXYKinematics_allowing_movement_without_homing could be derived from CoreXYKinematics and used instead.

Something similar could be done with a wrapper object delegating everything to the original object and replacing only the desired functionality.

Both object oriented ways can only override (=replace) complete functions.
This means functions should be small and do only one thing. This is a major rule in OOP.

In some cases (e.g. values or state kept in variables) it is possible to inherit the complete behavior and change something afterwards in the wrapper function.

f()      # the base functionality
  var = value

g()      # the wrapper
  call f()   # inherit all functionality from f()
  var = other_value  # override value

This would indeed work for self.limits.

But it would not work in many other cases. E.g. if var would be used in side f() or if some behavior in f() should be removed.

@KevinOConnor
Copy link
Collaborator

KevinOConnor commented Jun 7, 2018 via email

@oderwat
Copy link
Contributor

oderwat commented Jun 7, 2018

I think the only way I actually need moving without homing is after I pressed the "EMERGENCY" button / cut off serial. Then I want to move the head up as quick as possible to not drop and melt into whatever is on the plate. I may also want to move it to the side or front / back. But as the motors are off, I could do that manual as long as I am near the printer. So what about allowing a "move Z up for max of X mm" anytime?

Beside finding a "public agreed method" I am going to implement something, what I want to use later. It's open source after all.

P.S.: @KevinOConnor maybe not everybody is bad with "up/down" and "left/right". Do you really think it is fair to limit others to what seems to be your personal weakness?

@KevinOConnor
Copy link
Collaborator

KevinOConnor commented Jun 7, 2018 via email

@hg42
Copy link

hg42 commented Jun 7, 2018

the EMRGENCY case is my main argument, too.
E.g. my delta used to release one or two of it's magnetic arms and this sometimes moved the toolhead to a bad position (melting something etc.). I then wanted to move it away quickly. This should be possible.
Mechanical solutions don't help, if you are controlling it remotely.

Anyways, you said, the main reason is because of beginners (as you were, when it was frustrating, I also remember these times for me).
And:

If the user wants to turn off checks, then that's fine with me, but I do think it should be an explicit decision to do so. The default should be to do basic sanity checks on movements.

So, I think, there are these cases:

  • beginners that need protection against their own errors
  • more advanced users (but still non-programmers) that don't need this kind of protection anymore
  • programmers

The second group needs a simple solution (config) to disable the protection without fiddling with code. And not all programmers want to maintain their own forks only to disable such things.

So, please could you accept a PR for a setting to disable this?
Such a setting could be described in a document, that only advanced users will find. You could even call it "dangerous settings - keep away".

@oderwat
Copy link
Contributor

oderwat commented Jun 7, 2018

engineering a mechanical solution would be simpler and more effective

Yes. I have that. On my A8 I decoupled the Z Axis by using gravity and teflon matte for the connection. That worked very well and made it possible to lift up the Z-axis anytime, even while printing. On my Ender 3 I use coupler which separate when a sufficient force is applied. This already saved me from disasters while I was experimenting with different magnetic print plate solutions and forgot that a mirror is much thicker than a PEI foil :-)

Your comment above and comments elsewhere can be easily interpretted as insulting.

I could answer with some long smart ass comment about what I can "interpret" into what other people did to me. I hope you will eventually recognise that I am not spending time on GitHub Issues to insult people. I myself got upset because of ineffective communication. I usually try to let this not get into the way. I am a very pragmatic person. Maybe sitting in the same room with some of you guys would make all the difference.

Even if you don't feel like you are limiting others, you do and this is also your job as maintainer and main developer. I already got, that you probably will accept a PR. I just don't have the time to make a careful change, testing and contributing it.

@hg42
Copy link

hg42 commented Jun 7, 2018

for example, the klippy/extras/homing_override.py code disables the boundary checks in a single python statement

sorry, I don't see such a line...which one do you mean?

It's currently unclear to me, if you would only prefer a PR that uses a module to provide a special movement command or if you demand this (or a similar solution obeying your preferences).
I am asking because I think in this case a setting (or better two) is more appropriate, because its very simple, so it doesn't create a code maintainence nightmare.
A wrapper for the home and the motor_off would create additional dependencies that are invisible in the main code, so this would create such a nightmare over time, especially if there are more such things.

I admit, I appreciate some of your "different" solutions. It is kind of refreshing.

Though, being fairly new approaches, they might not take every situation into account.
E.g. I am not sure, if homing_override will always do what I want. I feel it should override only if called without parameters. But that would be another discussion.

@KevinOConnor
Copy link
Collaborator

KevinOConnor commented Jun 7, 2018 via email

@ich777
Copy link
Author

ich777 commented Jun 12, 2018

I think this topic can be closed now.

@ich777 ich777 closed this as completed Jun 12, 2018
@towe96
Copy link
Contributor

towe96 commented Jan 4, 2019

Is there a way around this by now?

It's probably the biggest gripe I have left with Klipper.
In what circumstance would there ever be G-Code sent to the printer that sends the carriage into the frame? And even then, stepper motors would skip long before there is any damage.

@jakep82
Copy link
Collaborator

jakep82 commented Jan 4, 2019

@towe96 It's extremely easy to make a mistake that could damage a printer. Not all printers use small nema 17 steppers and rubber belts. Imagine the damage that could be done by a powerful nema 23 and a ballscrew.

If you really want to move before homing, then use the force_move option.

@towe96
Copy link
Contributor

towe96 commented Jan 5, 2019

I've tried "force move", but it doesn't play nice with my CoreXY kinematics, since only one stepper moves.

Why shouldn't it at least be an option you can disable?
If the G-Code comes from the RPi, then there's a G28 somewhere in the start G-Code. If I just want to move the carriage around, then I'm typing the G-Code into the terminal by hand and know what's going to happen. I just don't see where that "faulty" G-Code would come from.

@dushyantahuja
Copy link
Contributor

dushyantahuja commented Jan 5, 2019 via email

@towe96
Copy link
Contributor

towe96 commented Jan 5, 2019

I've setup a macro called enable manual move with the following command: SET_KINEMATIC_POSITION X=100 Y=100 Z=10 Once I run this macro, I'm able to move the head manually using the controls in octoprint. It's an extra step, but works like a charm. Needless to say, you should home after done to ensure the kinematic positions are correct.

On Sat, 5 Jan 2019, 10:49 am towe96, @.***> wrote: I've tried "force move", but it doesn't play nice with my CoreXY kinematics, since only one stepper moves. Why shouldn't it at least be an option you can disable? If the G-Code comes from the RPi, then there's a G28 somewhere in the start G-Code. If I just want to move the carriage around, then I'm typing the G-Code into the terminal by hand and know what's going to happen. I just don't see where that "faulty" G-Code would come from. — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <#335 (comment)>, or mute the thread https://github.com/notifications/unsubscribe-auth/AGHpCRJPvczY9RBDSoAiNc8hHSCYWkXZks5vAINCgaJpZM4T7fOQ .

That works beautifully, thank you - though I still believe this should be a selectable option.

Another option might be implementing a macro that can be set during every startup-sequence / after every restart? If one would want to get rid of being forced to home, they could put in that command in their startup code.

@towe96
Copy link
Contributor

towe96 commented Apr 18, 2019

I found a permanent-ish solution I'm happy with.
My biggest gripe was with disallowing movement after an M84 command, e.g. at the end of a gcode file to allow free axis movement.

I therefore modified how M84 works.
Remove the following line from klipper/klippy/gcode.py:
cmd_M18_aliases = ["M84"]
Recompile Klipper by issuing:
klipper/scripts/install-octopi.sh
Add the following macro to your printer configuration file:

[gcode_macro M84]
gcode:
 M18
 SET_KINEMATIC_POSITION

Of course, you also need to have "Force Move" enabled:

[force_move]
enable_force_move: True

Then, issuing M84 works as would be expected - releasing the stepper motors, but restoring a "valid" kinematic state so that movements are still possible.

@zapl
Copy link

zapl commented Nov 19, 2019

It has just changed, no longer is it klippy/gcode.py, now you need to uncomment in klippy/extras/stepper_enable.py the line

gcode.register_command("M84", self.cmd_M18)

Would be nice if there was an actual permanent solution to this. Let me crash & destroy my printer if I choose to risk that.

@towe96
Copy link
Contributor

towe96 commented Feb 17, 2020

I still wish we could have a permanent solution for this "safety" feature.

@ld3300
Copy link
Contributor

ld3300 commented Feb 18, 2020

There is now a command that allows disabling and enabling steppers without losing their "Homed" state, which means they can continue to be moved when re-enabled. It is a modified version of M84 called SET_STEPPER_ENABLE. If set to 0 the stepper is turned off, but not disabled kinematically. It was originally intended to serve turning off extruders for filament switches, but works with all motors.

You also don't need to make any code changes to redefine M84 since rename_existing was added to GCODE_MACRO recently rename_existing. You can, from your config file, make M84 do whatever you want. If you combine it with SET_STEPPER_ENABLE STEPPER=<config name> ENABLE=0 to disable your motors, then you can re-enable the motors at any time and they will believe they are still where they were when turned off.

@towe96
Copy link
Contributor

towe96 commented Feb 22, 2020

Tried that today - it fails with "G-Code macro rename of different types"

Apparently you can't rename G1, M84 etc. "traditional" commands with SET_STEPPER_ENABLED "new Klipper" style commands.
Even then, I think you'd still need to home / SET_KINEMATIC_POSITION at least once after turning it on.

@ld3300
Copy link
Contributor

ld3300 commented Feb 22, 2020

@towe96
The implementation I would use is:

[gcode_macro M84]
rename_existing: M984 (or something like that)
gcode:
  SET_STEPPER_ENABLED STEPPER=stepper_x ENABLE=0
  SET_STEPPER_ENABLED STEPPER=stepper_y ENABLE=0
  SET_STEPPER_ENABLED STEPPER=stepper_z ENABLE=0

This would be a method at the end of print to turn off the motors then re-enable them at will later on, the flags that consider them homed do not get cleared

@zapl
Copy link

zapl commented Feb 27, 2020

it's SET_STEPPER_ENABLE not ENABLED 😄. So e.g. this is what I run sucessfully:

[gcode_macro M84]
rename_existing: M984
gcode:
  SET_STEPPER_ENABLE STEPPER=extruder ENABLE=0
  SET_STEPPER_ENABLE STEPPER=stepper_x ENABLE=0
  SET_STEPPER_ENABLE STEPPER=stepper_y ENABLE=0
  SET_STEPPER_ENABLE STEPPER=stepper_z ENABLE=0
  # uncomment for dual Z
  # SET_STEPPER_ENABLE STEPPER=stepper_z1 ENABLE=0

[gcode_macro M18]
rename_existing: M918
gcode:
  M84

You also don't need the [force_move] section anymore.

@ld3300
Copy link
Contributor

ld3300 commented Feb 28, 2020

it's SET_STEPPER_ENABLE not ENABLED 😄. So e.g. this is what I run sucessfully:

[gcode_macro M84]
rename_existing: M984
gcode:
  SET_STEPPER_ENABLE STEPPER=stepper_x ENABLE=0
  SET_STEPPER_ENABLE STEPPER=stepper_y ENABLE=0
  SET_STEPPER_ENABLE STEPPER=stepper_z ENABLE=0
  # uncomment for dual Z
  # SET_STEPPER_ENABLE STEPPER=stepper_z1 ENABLE=0

[gcode_macro M18]
rename_existing: M918
gcode:
  M84

You also don't need the [force_move] section anymore.

LOL, I created the gcode command and I can't even quote it right.

@towe96
Copy link
Contributor

towe96 commented Jun 2, 2020

I'd still love to see an easier config option that disables the check whether the position is known - just like Marlin's "NO_MOTION_BEFORE_HOMING" which is disabled by default for obvious usability reasons.

@towe96
Copy link
Contributor

towe96 commented Jul 28, 2020

This bug really needs a fix.

@dushyantahuja
Copy link
Contributor

dushyantahuja commented Jul 28, 2020 via email

@towe96
Copy link
Contributor

towe96 commented Jul 28, 2020

It's not a bug, it is how klipper is designed. There are workarounds listed in this thread that you can use.

On Tue, 28 Jul 2020, 1:07 pm Tobias Weiß, @.***> wrote: This bug really needs a fix. — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#335 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQ6SCNS3442UPBIJZUF3KLR525PBANCNFSM4E7N6OIA .

Those are all cumbersome. Everything in Klipper is configurable, why not this silly "safety" bug?

@Zamundaaa
Copy link

I agree. I think the default is good but it should be possible to easily turn it off, at least for one session or something like that.

@matthuszagh
Copy link

matthuszagh commented Nov 5, 2020

I'd also like to see this as a configuration option. While the workarounds may work after a completed print, they don't handle other situations. For instance, sometimes I cancel a print and would then like to immediately move the z axis up to have access to the bed. However, with the workaround given above this doesn't work. Moreover, I have to home the xy axes first and then home the z-axis. I'm not particularly keen on homing the z-axis while there is a print on the bed.

While it's nice that Klipper helps us out here, in this particular case it feels more like it's getting in the way.

@int3r
Copy link

int3r commented Nov 18, 2020

Agreed with the other posts in this thread, would really prefer a toggle or a built in command somewhere that just allows you to move the Z axis independent of whether or not it has been homed, especially for failed prints where you need to move the Z axis up to avoid the extruder melting further into the printed material making it difficult to remove and warping what's left of the print.

I've had prints "fail" on the last layer, and what was an otherwise perfect print ended up with a completely warped top because it wouldn't let me move the Z axis up a few mm after failing.

It's also particularly annoying if you're printing while away from your printer, and the print fails. The heaters all turn off (for obvious safety reasons) then the print cools and melds to your extruder/hot end. Then if the print stays stuck to the bed, you have to put a bunch of unnecessary stress on the motors to get it unjammed and/or risk damaging the bed.

I understand its use as a safety check in default scenarios, but I know that people absolutely will run into this issue very frequently and it feels like a worthy add in.

@KevinOConnor
Copy link
Collaborator

This is covered in the FAQ: https://www.klipper3d.org/FAQ.html#why-cant-i-move-the-stepper-before-homing-the-printer .

In particular, if you really want to forcibly move the stepper motors then enable [force_move] in the config file and issue a bare SET_KINEMATIC_POSITION command. Once that command is issued the printer will think it is at its last commanded position, and one can move the axes as desired. (As noted in the FAQ, though, it's probably much simpler to just tell OctoPrint not to turn off the motors on a cancel request.)

-Kevin

@int3r
Copy link

int3r commented Nov 18, 2020

First off, thanks for the insanely fast response, you're probably one of the most active devs I've ever seen and I admire the heck out of that.

Second, I somehow completely missed the main FAQ page topic for this, and had been diving around all the deeper config files etc. And setting an Octoprint cancel sequence will definitely help alleviate a lot of the issue I described. So thanks for pointing that out! :)

I have another quick question/case for you along this line: if for some reason the print fails i.e. because of an extruder heater not heating at expected rate, and this causes the print to halt, is there any way to automatically have the printer move the Z axis up by X mm, and possibly home X/Y or something similar?

Thanks again for everything you've done and continue to do for the community!

@KevinOConnor
Copy link
Collaborator

if for some reason the print fails i.e. because of an extruder heater not heating at expected rate, and this causes the print to halt, is there any way to automatically have the printer move the Z axis up by X mm, and possibly home X/Y or something similar?

It's possible to use gcode_macro to perform lots of functionality like the above. However, in the examples you cite, where the micro-controller itself goes into an emergency shutdown state, it is not currently possible to program the actions taken during that shutdown.

-Kevin

@github-actions github-actions bot locked and limited conversation to collaborators Nov 29, 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