############################################################
###### AXE_MAP DETECTION AND ACCELEROMETER VALIDATION ######
############################################################
# Written by Frix_x#0161 #

[gcode_macro AXES_MAP_CALIBRATION]
gcode:
    {% set z_height = params.Z_HEIGHT|default(20)|int %} # z height to put the toolhead before starting the movements
    {% set speed = params.SPEED|default(80)|float * 60 %} # feedrate for the movements
    {% set accel = params.ACCEL|default(1500)|int %} # accel value used to move on the pattern
    {% set feedrate_travel = params.TRAVEL_SPEED|default(120)|int * 60 %} # travel feedrate between moves
    {% set accel_chip = params.ACCEL_CHIP|default("adxl345") %} # ADXL chip name in the config

    {% set mid_x = printer.toolhead.axis_maximum.x|float / 2 %}
    {% set mid_y = printer.toolhead.axis_maximum.y|float / 2 %}

    {% set accel = [accel, printer.configfile.settings.printer.max_accel]|min %}
    {% set old_accel = printer.toolhead.max_accel %}
    {% set old_cruise_ratio = printer.toolhead.minimum_cruise_ratio %}
    {% set old_sqv = printer.toolhead.square_corner_velocity %}


    {% if not 'xyz' in printer.toolhead.homed_axes %}
        { action_raise_error("Must Home printer first!") }
    {% endif %}

    {action_respond_info("")}
    {action_respond_info("Starting accelerometer axe_map calibration")}
    {action_respond_info("This operation can not be interrupted by normal means. Hit the \"emergency stop\" button to stop it if needed")}
    {action_respond_info("")}

    SAVE_GCODE_STATE NAME=STATE_AXESMAP_CALIBRATION

    G90

    # Set the wanted acceleration values (not too high to avoid oscillation, not too low to be able to reach constant speed on each segments)
    SET_VELOCITY_LIMIT ACCEL={accel} MINIMUM_CRUISE_RATIO=0 SQUARE_CORNER_VELOCITY={[(accel / 1000), 5.0]|max}
    
    # Going to the start position
    G1 Z{z_height} F{feedrate_travel / 8}
    G1 X{mid_x - 15} Y{mid_y - 15} F{feedrate_travel}
    G4 P500

    ACCELEROMETER_MEASURE CHIP={accel_chip}
    G4 P1000 # This first waiting time is to record the background accelerometer noise before moving
    G1 X{mid_x + 15} F{speed}
    G4 P1000
    G1 Y{mid_y + 15} F{speed}
    G4 P1000
    G1 Z{z_height + 15} F{speed}
    G4 P1000
    ACCELEROMETER_MEASURE CHIP={accel_chip} NAME=axemap

    RESPOND MSG="Analysis of the movements..."
    RUN_SHELL_COMMAND CMD=shaketune PARAMS="--type axesmap --accel {accel|int} --chip_name {accel_chip}"

    # Restore the previous acceleration values
    SET_VELOCITY_LIMIT ACCEL={old_accel} MINIMUM_CRUISE_RATIO={old_cruise_ratio} SQUARE_CORNER_VELOCITY={old_sqv}

    RESTORE_GCODE_STATE NAME=STATE_AXESMAP_CALIBRATION
