moggieuk / Happy-Hare

MMU software driver for Klipper (ERCF, Tradrack, Prusa)
GNU General Public License v3.0
458 stars 112 forks source link

Tool change macro enhancement. #170

Open mlee12382 opened 7 months ago

mlee12382 commented 7 months ago

I would like to propose an enhancement for the tool change macros (T0-Tn). I have my slicer set up to pass the Spoolman ID to the printer in the filament gcode. I have done the following to my tool change macros to check the ID passed from the slicer against what is loaded in the MMU and it will either pause the printer if it doesn't match or it will continue with the tool change.

[gcode_macro T0]
description: Tool change macro
  useage: T0 [SPOOLMAN_ID=<id>]
gcode: 
    {% set SPOOLMAN_ID = params.SPOOLMAN_ID|default(None) %}
    {% if SPOOLMAN_ID != None %}
      {% set index_to_check = 0 %}
      {% if mmu_state_gate_spool_id|length > index_to_check %}
          {% set value_to_check = mmu_state_gate_spool_id[index_to_check] %}
          {% if value_to_check != SPOOLMAN_ID %}
              {action_respond_info("Please Check Spools Against Current Print")}
              PAUSE
          {% endif %}
      {% endif %}
    {% endif %}
    MMU_CHANGE_TOOL TOOL=0
moggieuk commented 7 months ago

That's an interesting idea but the code is incomplete. What is mmu_state_gate_spool_id. Also don't forget Tool-to-Gate mapping..

mlee12382 commented 7 months ago

mmu_state_gate_spool_id is the stored Spoolman ID in the variables.cfg

[Variables]
active_tool = 'T0'
bed_surfaces = {'active': 'default', 'available': {u'default': {'offset': -0.03}}, 'probe_z': 0.0, 'endstop_z': 0.0}
ercf_state_gate_selected = 0
ercf_state_gate_status = [-1, -1, -1, -1, -1, 1]
ercf_state_loaded_status = 0
ercf_state_tool_selected = -1
mmu_calibration_0 = 1.0
mmu_calibration_1 = 1.034782
mmu_calibration_2 = 1.029565
mmu_calibration_3 = 0.827826
mmu_calibration_4 = 0.834782
mmu_calibration_5 = 0.831884
mmu_calibration_bowden_length = 1674.8
mmu_calibration_clog_length = 7.5
mmu_encoder_resolution = 1.056803
mmu_gear_rotation_distance = 22.78275
mmu_selector_bypass = 51.6
mmu_selector_offsets = [0.0, 21.2, 41.9, 68.9, 89.8, 110.8]
mmu_state_enable_endless_spool = 1
mmu_state_endless_spool_groups = [0, 1, 2, 3, 4, 5]
mmu_state_filament_pos = 10
mmu_state_gate_color = ['000000', '001ACA', '0F7332', 'E700F2', '000000', 'FFFFFF']
mmu_state_gate_material = ['PLA', 'PLA', 'PLA', 'PLA', 'PLA', 'PLA']
mmu_state_gate_selected = 0
mmu_state_gate_spool_id = [1, 28, 18, 29, 30, 31]
mmu_state_gate_status = [1, 2, 1, 2, 1, 1]
mmu_state_tool_selected = 0
mmu_state_tool_to_gate_map = [0, 1, 2, 3, 4, 5]
mmu_statistics_gate_0 = {'servo_retries': 0, 'load_failures': 3, 'load_delta': 3713.266, 'pauses': 0, 'unload_delta': -117.943, 'unload_failures': 0, 'unloads': 0, 'loads': 0, 'quality': 0.47140880964864723, 'unload_distance': 3259.6, 'load_distance': 7439.553}
mmu_statistics_gate_1 = {'servo_retries': 1, 'load_failures': 3, 'load_delta': 424.495, 'pauses': 0, 'unload_delta': -200.47, 'unload_failures': 0, 'unloads': 0, 'loads': 0, 'quality': 0.9090021372552929, 'unload_distance': 8199.0, 'load_distance': 6992.525}
mmu_statistics_gate_2 = {'servo_retries': 0, 'load_failures': 1, 'load_delta': 752.336, 'pauses': 5, 'unload_delta': 29.647, 'unload_failures': 0, 'unloads': 0, 'loads': 0, 'quality': 0.9774051265846058, 'unload_distance': 3284.6, 'load_distance': 5771.094}
mmu_statistics_gate_3 = {'servo_retries': 12, 'load_failures': 4, 'load_delta': 1297.218, 'pauses': 3, 'unload_delta': -358.58, 'unload_failures': 0, 'unloads': 0, 'loads': 0, 'quality': 0.922868462879813, 'unload_distance': 14893.2, 'load_distance': 29602.63}
mmu_statistics_gate_4 = {'servo_retries': 23, 'load_failures': 2, 'load_delta': -200.649, 'pauses': 4, 'unload_delta': 371.823, 'unload_failures': 1, 'unloads': 0, 'loads': 0, 'quality': 0.9467361400429632, 'unload_distance': 13238.4, 'load_distance': 18061.966}
mmu_statistics_gate_5 = {'servo_retries': 0, 'load_failures': 0, 'load_delta': -77.845, 'pauses': 1, 'unload_delta': 1654.339, 'unload_failures': 0, 'unloads': 0, 'loads': 0, 'quality': 1.0955113903851081, 'unload_distance': 6619.2, 'load_distance': 4856.369}
mmu_statistics_swaps = {'total_swaps': 31, 'total_pauses': 13, 'time_spent_unloading': 1188.89, 'time_spent_loading': 1533.61, 'time_spent_paused': 777.06}

What do you mean about the tool-to-gate mapping? I'm sure we can figure out a way to make the enhancements more robust, it just a crude implementation at the moment.

moggieuk commented 7 months ago

Oh, yes. Sorry I don't expect you to be pulling from mmu_vars.cfg - updates may be delayed. Far better to use the printer variable: printer.mmu.gate_spool_id Which is always right up-to-date.

To apply TTG map you would want an indirect. Something like:

    {% set ttg_map = printer.mmu.ttg_map %}
    {% set gate = ttg_map[tool] %}               # Make sure map to correct gate in case of TTG map

Because T1 may not be mapped to gate 1, for example...

mlee12382 commented 7 months ago

Oh, I see what you're saying, I should do the check based on the gate mapping instead of just assuming t0 = gate 0. Do printer.mmu.gate_spool_id and printer.mmu.ttg_map return as strings the same as the values in the variables file so the structuring of the macro would be the same, I would just use the live values instead of the stored values?

mlee12382 commented 7 months ago

Something more like this maybe?

[gcode_macro T0]
description: Tool change macro for Tool 0
  usage: T0 [SPOOLMAN_ID=<id>]
gcode:
    {% set tool = "0" %}
    {% set ttg_map = printer.mmu.ttg_map %}
    {% set gate = ttg_map[tool] %}
    {% set SPOOLMAN_ID = params.SPOOLMAN_ID|default(None) %}

    {% if SPOOLMAN_ID != None %}
        {% if printer.mmu.gate_spool_id|length > gate %}
            {% set value_to_check = printer.mmu.gate_spool_id[gate] %}
            {% if value_to_check != SPOOLMAN_ID %}
                {action_respond_info("Please Check Spools Against Current Print")}
                PAUSE
            {% endif %}
        {% endif %}
    {% endif %}

    MMU_CHANGE_TOOL TOOL=0
moggieuk commented 7 months ago

Ok, I think a better idea is to upload the required array of spoolman ID's from your slicer and pass to you print_start macro. You can do this as an array for each tool used. Then in the print start you would MMU_GATE_MAP GATE=xx SPOOLID=yyy in a loop one time in print start. After all gates are set, call: MMU_GATE_MAP REFRESH=1 this will cause HH to talk to spoolman and pull color / material, etc.

I don't think it is appropriate or necessary to do this on every toolchange. The point of the gate_map is to track what is actually loaded in your MMU.

mlee12382 commented 7 months ago

I am unsure how to get the slicer to pass information about filament or tools being used other than the active tool / filament, which is why I am doing it in the tool change macro.

moggieuk commented 7 months ago

where do you get the spoolman ID in the T0 SPOOLMAN_ID=xxx approach?
Is this something that you would customize in your slicer or does the slicer have a connection to Spoolman (maybe there have been developments I'm not aware of).

mlee12382 commented 7 months ago

SuperSlicer allows custom variables in the notes section of the filament profiles so I set a SPOOLMAN_ID variable there that I then pass through the toolchange gcode.

moggieuk commented 6 months ago

Thanks. After pushing v2.5.1 there are a couple of folks on the Discord forum (maybe you lol) that are experimenting with this. As the idea develops I'll look at better support in HH if necessary...

Romano26 commented 1 month ago

hello I have the same problem is it possible to change "mmu_state_gate_spool_id" with the orcaslicer start gcode? thk