naikymen / klipper-for-cnc

Fork of the Klipper 3D-printer firmware, plus features for more general CNC.
https://klipper.discourse.group/t/klipper-for-cnc-initiatives-and-projects-list/5698
GNU General Public License v3.0
66 stars 9 forks source link

printer.toolhead.position not updated during macro #17

Open noobydp opened 3 months ago

noobydp commented 3 months ago

Describe the bug I'm writing a series of macros that use the multiprobe2 / G38.x commands to probe different things: probe workpiece X, Y, Z, measure tool length etc.

I basically want to use the tool location to calculate workpiece offsets which I then apply using SET_GCODE_OFFSET, and also to measure the tool length to automatically adjust Z offset when the tool is changed.

I've noticed that during the execution of a macro, the printer.toolhead.position values are not updated, meaning I cannot use them after probing has triggered to determine the location.

(PS - I assume this is an issuer with Klipper, but thought I'd ask here for your insight before I raise the issue in the main repo)

The example macro below is the simplest form I could think of. tool_setter is a limit switch thats directly below the tool.

The flow is:

  1. Toolhead moves to the correct position, position is reported
  2. multiprobe2 is executed
  3. The new toolhead.position values are used to do calculations

The issue is the reported position in step 1 and step 3 are the same

To Reproduce

[gcode_macro TEST_POSITION]
gcode:
    RESPOND PREFIX='info' MSG='toolhead: {printer.toolhead.position}' # step 1
    MULTIPROBE2 PROBE_NAME=tool_setter Z=0 F=10 # step 2
    RESPOND PREFIX='info' MSG='toolhead: {printer.toolhead.position}' # step 3

6:17 PM info toolhead: Coord(x=1.0000000000000058, y=344.20000000070434, z=113.003125, a=None, b=None, c=None, e=0.0) 6:17 PM probe trigger at x=1.000 y=344.200 z=30.597 e=0.000 6:17 PM info toolhead: Coord(x=1.0000000000000058, y=344.20000000070434, z=113.003125, a=None, b=None, c=None, e=0.0)

Upload your klipper config file and log files

Expected behavior printer.toolhead.position should report the positions within the macro exeuction

Screenshots If applicable, add screenshots to help explain your problem.

Additional context Add any other context about the problem here.

naikymen commented 2 months ago

Hello @noobydp thanks for reporting. I'll try to have a look at this over the weekend.

naikymen commented 2 months ago

Hello again!

I'm thinking that this is an upstream bug. I've tested your script on the latest commit: https://github.com/Klipper3d/klipper/commit/b7f7b8a346388cc32d80b6e6f60e5fdb4cbd3ce6

With a slightly different macro:

[respond]
# Enable M118 and RESPOND.

[gcode_macro TEST_POSITION]
gcode:
    RESPOND PREFIX='info' MSG='toolhead: {printer.toolhead.position}' # step 1
    G1 X1 # new step 2
    RESPOND PREFIX='info' MSG='toolhead: {printer.toolhead.position}' # step 3

It seems to me that the RESPOND commad does not "wait" for moves to finish at all.

Have you tested on upstream klipper yet?

naikymen commented 2 months ago

Even adding G4 or M400 commands in between does not help:

image

I'm still testing on upstream klipper.

naikymen commented 2 months ago

Figured it out.

The issue is that the whole macro is evaluated before execution. This is upstream behaviour.

You need to send the RESPOND command separately.

This, for example, works just fine:

TEST_POSITION
G1 X1
M400
TEST_POSITION
[gcode_macro TEST_POSITION]
gcode:
    RESPOND PREFIX='info' MSG='toolhead: {printer.toolhead.position}'

image

naikymen commented 2 months ago

Try it out with and without M400. Because of how probing works in klipper, you will probably get different answers.

The position you are looking for is probably the one you'd get with the M400 command. I have not testesd it yet with MULTIPROBE.

Please report :)

noobydp commented 2 months ago

Thanks, I'll try in the next couple days and raise in mainline klipper.

For the custom probing macros I'm writing (e.g. find hole center), I've ended up using delayed gcode macros to allow me to step though the logic and get updated position.

Conceptually it's similar to your example with the test_position macro.