Merge pull request #5175 from thinkyhead/rc_dualx_homing
Unpark when using Z_SAFE_HOMING with Dual X
This commit is contained in:
		| @@ -294,8 +294,8 @@ void update_software_endstops(AxisEnum axis); | ||||
| extern float soft_endstop_min[XYZ]; | ||||
| extern float soft_endstop_max[XYZ]; | ||||
|  | ||||
| #define LOGICAL_POSITION(POS, AXIS) (POS + home_offset[AXIS] + position_shift[AXIS]) | ||||
| #define RAW_POSITION(POS, AXIS)     (POS - home_offset[AXIS] - position_shift[AXIS]) | ||||
| #define LOGICAL_POSITION(POS, AXIS) ((POS) + home_offset[AXIS] + position_shift[AXIS]) | ||||
| #define RAW_POSITION(POS, AXIS)     ((POS) - home_offset[AXIS] - position_shift[AXIS]) | ||||
| #define LOGICAL_X_POSITION(POS)     LOGICAL_POSITION(POS, X_AXIS) | ||||
| #define LOGICAL_Y_POSITION(POS)     LOGICAL_POSITION(POS, Y_AXIS) | ||||
| #define LOGICAL_Z_POSITION(POS)     LOGICAL_POSITION(POS, Z_AXIS) | ||||
|   | ||||
| @@ -1312,22 +1312,20 @@ bool get_target_extruder_from_command(int code) { | ||||
|  | ||||
|   static DualXMode dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE; | ||||
|  | ||||
|   static float x_home_pos(int extruder) { | ||||
|   static float x_home_pos(const int extruder) { | ||||
|     if (extruder == 0) | ||||
|       return LOGICAL_X_POSITION(base_home_pos(X_AXIS)); | ||||
|     else | ||||
|       /** | ||||
|        * In dual carriage mode the extruder offset provides an override of the | ||||
|        * second X-carriage offset when homed - otherwise X2_HOME_POS is used. | ||||
|        * This allow soft recalibration of the second extruder offset position | ||||
|        * second X-carriage position when homed - otherwise X2_HOME_POS is used. | ||||
|        * This allows soft recalibration of the second extruder home position | ||||
|        * without firmware reflash (through the M218 command). | ||||
|        */ | ||||
|       return (hotend_offset[X_AXIS][1] > 0) ? hotend_offset[X_AXIS][1] : X2_HOME_POS; | ||||
|       return LOGICAL_X_POSITION(hotend_offset[X_AXIS][1] > 0 ? hotend_offset[X_AXIS][1] : X2_HOME_POS); | ||||
|   } | ||||
|  | ||||
|   static int x_home_dir(int extruder) { | ||||
|     return (extruder == 0) ? X_HOME_DIR : X2_HOME_DIR; | ||||
|   } | ||||
|   static int x_home_dir(const int extruder) { return extruder ? X2_HOME_DIR : X_HOME_DIR; } | ||||
|  | ||||
|   static float inactive_extruder_x_pos = X2_MAX_POS; // used in mode 0 & 1 | ||||
|   static bool active_extruder_parked = false;        // used in mode 1 & 2 | ||||
| @@ -1351,25 +1349,33 @@ void update_software_endstops(AxisEnum axis) { | ||||
|   float offs = LOGICAL_POSITION(0, axis); | ||||
|  | ||||
|   #if ENABLED(DUAL_X_CARRIAGE) | ||||
|     bool did_update = false; | ||||
|     if (axis == X_AXIS) { | ||||
|  | ||||
|       // In Dual X mode hotend_offset[X] is T1's home position | ||||
|       float dual_max_x = max(hotend_offset[X_AXIS][1], X2_MAX_POS); | ||||
|  | ||||
|       if (active_extruder != 0) { | ||||
|         // T1 can move from X2_MIN_POS to X2_MAX_POS or X2 home position (whichever is larger) | ||||
|         soft_endstop_min[X_AXIS] = X2_MIN_POS + offs; | ||||
|         soft_endstop_max[X_AXIS] = dual_max_x + offs; | ||||
|         return; | ||||
|       } | ||||
|       else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) { | ||||
|         // In Duplication Mode, T0 can move as far left as X_MIN_POS | ||||
|         // but not so far to the right that T1 would move past the end | ||||
|         soft_endstop_min[X_AXIS] = base_min_pos(X_AXIS) + offs; | ||||
|         soft_endstop_max[X_AXIS] = min(base_max_pos(X_AXIS), dual_max_x - duplicate_extruder_x_offset) + offs; | ||||
|         return; | ||||
|       } | ||||
|       else { | ||||
|         // In other modes, T0 can move from X_MIN_POS to X_MAX_POS | ||||
|         soft_endstop_min[axis] = base_min_pos(axis) + offs; | ||||
|         soft_endstop_max[axis] = base_max_pos(axis) + offs; | ||||
|       } | ||||
|     } | ||||
|     else | ||||
|   #endif | ||||
|   { | ||||
|   #else | ||||
|     soft_endstop_min[axis] = base_min_pos(axis) + offs; | ||||
|     soft_endstop_max[axis] = base_max_pos(axis) + offs; | ||||
|   } | ||||
|   #endif | ||||
|  | ||||
|   #if ENABLED(DEBUG_LEVELING_FEATURE) | ||||
|     if (DEBUGGING(LEVELING)) { | ||||
| @@ -1418,6 +1424,7 @@ static void set_home_offset(AxisEnum axis, float v) { | ||||
|  * current_position to home, because neither X nor Y is at home until | ||||
|  * both are at home. Z can however be homed individually. | ||||
|  * | ||||
|  * Callers must sync the planner position after calling this! | ||||
|  */ | ||||
| static void set_axis_is_at_home(AxisEnum axis) { | ||||
|   #if ENABLED(DEBUG_LEVELING_FEATURE) | ||||
| @@ -1434,12 +1441,8 @@ static void set_axis_is_at_home(AxisEnum axis) { | ||||
|   update_software_endstops(axis); | ||||
|  | ||||
|   #if ENABLED(DUAL_X_CARRIAGE) | ||||
|     if (axis == X_AXIS && (active_extruder != 0 || dual_x_carriage_mode == DXC_DUPLICATION_MODE)) { | ||||
|       if (active_extruder != 0) | ||||
|         current_position[X_AXIS] = x_home_pos(active_extruder); | ||||
|       else | ||||
|         current_position[X_AXIS] = LOGICAL_X_POSITION(base_home_pos(X_AXIS)); | ||||
|       update_software_endstops(X_AXIS); | ||||
|     if (axis == X_AXIS && (active_extruder == 1 || dual_x_carriage_mode == DXC_DUPLICATION_MODE)) { | ||||
|       current_position[X_AXIS] = x_home_pos(active_extruder); | ||||
|       return; | ||||
|     } | ||||
|   #endif | ||||
| @@ -3252,13 +3255,21 @@ inline void gcode_G4() { | ||||
|           #endif | ||||
|         ) | ||||
|     ) { | ||||
|  | ||||
|       #if HOMING_Z_WITH_PROBE | ||||
|         destination[X_AXIS] -= X_PROBE_OFFSET_FROM_EXTRUDER; | ||||
|         destination[Y_AXIS] -= Y_PROBE_OFFSET_FROM_EXTRUDER; | ||||
|       #endif | ||||
|  | ||||
|       #if ENABLED(DEBUG_LEVELING_FEATURE) | ||||
|         if (DEBUGGING(LEVELING)) DEBUG_POS("Z_SAFE_HOMING", destination); | ||||
|       #endif | ||||
|  | ||||
|       // This causes the carriage on Dual X to unpark | ||||
|       #if ENABLED(DUAL_X_CARRIAGE) | ||||
|         active_extruder_parked = false; | ||||
|       #endif | ||||
|  | ||||
|       do_blocking_move_to_xy(destination[X_AXIS], destination[Y_AXIS]); | ||||
|       HOMEAXIS(Z); | ||||
|     } | ||||
| @@ -3407,20 +3418,31 @@ inline void gcode_G28() { | ||||
|  | ||||
|     // Home X | ||||
|     if (home_all_axis || homeX) { | ||||
|  | ||||
|       #if ENABLED(DUAL_X_CARRIAGE) | ||||
|         int tmp_extruder = active_extruder; | ||||
|         active_extruder = !active_extruder; | ||||
|  | ||||
|         // Always home the 2nd (right) extruder first | ||||
|         active_extruder = 1; | ||||
|         HOMEAXIS(X); | ||||
|  | ||||
|         // Remember this extruder's position for later tool change | ||||
|         inactive_extruder_x_pos = RAW_X_POSITION(current_position[X_AXIS]); | ||||
|         active_extruder = tmp_extruder; | ||||
|  | ||||
|         // Home the 1st (left) extruder | ||||
|         active_extruder = 0; | ||||
|         HOMEAXIS(X); | ||||
|         // reset state used by the different modes | ||||
|  | ||||
|         // Consider the active extruder to be parked | ||||
|         memcpy(raised_parked_position, current_position, sizeof(raised_parked_position)); | ||||
|         delayed_move_time = 0; | ||||
|         active_extruder_parked = true; | ||||
|  | ||||
|       #else | ||||
|  | ||||
|         HOMEAXIS(X); | ||||
|  | ||||
|       #endif | ||||
|  | ||||
|       #if ENABLED(DEBUG_LEVELING_FEATURE) | ||||
|         if (DEBUGGING(LEVELING)) DEBUG_POS("> homeX", current_position); | ||||
|       #endif | ||||
| @@ -7446,10 +7468,8 @@ inline void invalid_extruder_error(const uint8_t &e) { | ||||
| void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool no_move/*=false*/) { | ||||
|   #if ENABLED(MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1 | ||||
|  | ||||
|     if (tmp_extruder >= MIXING_VIRTUAL_TOOLS) { | ||||
|       invalid_extruder_error(tmp_extruder); | ||||
|       return; | ||||
|     } | ||||
|     if (tmp_extruder >= MIXING_VIRTUAL_TOOLS) | ||||
|       return invalid_extruder_error(tmp_extruder); | ||||
|  | ||||
|     // T0-Tnnn: Switch virtual tool by changing the mix | ||||
|     for (uint8_t j = 0; j < MIXING_STEPPERS; j++) | ||||
| @@ -7459,10 +7479,8 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n | ||||
|  | ||||
|     #if HOTENDS > 1 | ||||
|  | ||||
|       if (tmp_extruder >= EXTRUDERS) { | ||||
|         invalid_extruder_error(tmp_extruder); | ||||
|         return; | ||||
|       } | ||||
|       if (tmp_extruder >= EXTRUDERS) | ||||
|         return invalid_extruder_error(tmp_extruder); | ||||
|  | ||||
|       float old_feedrate_mm_s = feedrate_mm_s; | ||||
|  | ||||
| @@ -7490,22 +7508,28 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n | ||||
|             } | ||||
|           #endif | ||||
|  | ||||
|           if (dual_x_carriage_mode == DXC_AUTO_PARK_MODE && IsRunning() && | ||||
|               (delayed_move_time || current_position[X_AXIS] != x_home_pos(active_extruder)) | ||||
|           const float xhome = x_home_pos(active_extruder); | ||||
|           if (dual_x_carriage_mode == DXC_AUTO_PARK_MODE | ||||
|               && IsRunning() | ||||
|               && (delayed_move_time || current_position[X_AXIS] != xhome) | ||||
|           ) { | ||||
|             float raised_z = current_position[Z_AXIS] + TOOLCHANGE_PARK_ZLIFT; | ||||
|             #if ENABLED(max_software_endstops) | ||||
|               NOMORE(raised_z, soft_endstop_max[Z_AXIS]); | ||||
|             #endif | ||||
|             #if ENABLED(DEBUG_LEVELING_FEATURE) | ||||
|               if (DEBUGGING(LEVELING)) { | ||||
|                 SERIAL_ECHOPAIR("Raise to ", current_position[Z_AXIS] + TOOLCHANGE_PARK_ZLIFT); SERIAL_EOL; | ||||
|                 SERIAL_ECHOPAIR("MoveX to ", x_home_pos(active_extruder)); SERIAL_EOL; | ||||
|                 SERIAL_ECHOPAIR("Lower to ", current_position[Z_AXIS]); SERIAL_EOL; | ||||
|                 SERIAL_ECHOLNPAIR("Raise to ", raised_z); | ||||
|                 SERIAL_ECHOLNPAIR("MoveX to ", xhome); | ||||
|                 SERIAL_ECHOLNPAIR("Lower to ", current_position[Z_AXIS]); | ||||
|               } | ||||
|             #endif | ||||
|             // Park old head: 1) raise 2) move to park position 3) lower | ||||
|             for (uint8_t i = 0; i < 3; i++) | ||||
|               planner.buffer_line( | ||||
|                 i == 0 ? current_position[X_AXIS] : x_home_pos(active_extruder), | ||||
|                 i == 0 ? current_position[X_AXIS] : xhome, | ||||
|                 current_position[Y_AXIS], | ||||
|                 current_position[Z_AXIS] + (i == 2 ? 0 : TOOLCHANGE_PARK_ZLIFT), | ||||
|                 i == 2 ? current_position[Z_AXIS] : raised_z, | ||||
|                 current_position[E_AXIS], | ||||
|                 planner.max_feedrate_mm_s[i == 1 ? X_AXIS : Z_AXIS], | ||||
|                 active_extruder | ||||
| @@ -7513,9 +7537,11 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n | ||||
|             stepper.synchronize(); | ||||
|           } | ||||
|  | ||||
|           // apply Y & Z extruder offset (x offset is already used in determining home pos) | ||||
|           // Apply Y & Z extruder offset (X offset is used as home pos with Dual X) | ||||
|           current_position[Y_AXIS] -= hotend_offset[Y_AXIS][active_extruder] - hotend_offset[Y_AXIS][tmp_extruder]; | ||||
|           current_position[Z_AXIS] -= hotend_offset[Z_AXIS][active_extruder] - hotend_offset[Z_AXIS][tmp_extruder]; | ||||
|  | ||||
|           // Activate the new extruder | ||||
|           active_extruder = tmp_extruder; | ||||
|  | ||||
|           // This function resets the max/min values - the current position may be overwritten below. | ||||
| @@ -7525,9 +7551,14 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n | ||||
|             if (DEBUGGING(LEVELING)) DEBUG_POS("New Extruder", current_position); | ||||
|           #endif | ||||
|  | ||||
|           // Only when auto-parking are carriages safe to move | ||||
|           if (dual_x_carriage_mode != DXC_AUTO_PARK_MODE) no_move = true; | ||||
|  | ||||
|           switch (dual_x_carriage_mode) { | ||||
|             case DXC_FULL_CONTROL_MODE: | ||||
|               // New current position is the position of the activated extruder | ||||
|               current_position[X_AXIS] = LOGICAL_X_POSITION(inactive_extruder_x_pos); | ||||
|               // Save the inactive extruder's position (from the old current_position) | ||||
|               inactive_extruder_x_pos = RAW_X_POSITION(destination[X_AXIS]); | ||||
|               break; | ||||
|             case DXC_AUTO_PARK_MODE: | ||||
| @@ -7541,7 +7572,10 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n | ||||
|               delayed_move_time = 0; | ||||
|               break; | ||||
|             case DXC_DUPLICATION_MODE: | ||||
|               active_extruder_parked = (active_extruder == 0); // this triggers the second extruder to move into the duplication position | ||||
|               // If the new extruder is the left one, set it "parked" | ||||
|               // This triggers the second extruder to move into the duplication position | ||||
|               active_extruder_parked = (active_extruder == 0); | ||||
|  | ||||
|               if (active_extruder_parked) | ||||
|                 current_position[X_AXIS] = LOGICAL_X_POSITION(inactive_extruder_x_pos); | ||||
|               else | ||||
| @@ -7566,9 +7600,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n | ||||
|             float z_diff = hotend_offset[Z_AXIS][active_extruder] - hotend_offset[Z_AXIS][tmp_extruder], | ||||
|                   z_raise = 0.3 + (z_diff > 0.0 ? z_diff : 0.0); | ||||
|  | ||||
|             set_destination_to_current(); | ||||
|  | ||||
|             // Always raise by some amount | ||||
|             // Always raise by some amount (destination copied from current_position earlier) | ||||
|             destination[Z_AXIS] += z_raise; | ||||
|             planner.buffer_line_kinematic(destination, planner.max_feedrate_mm_s[Z_AXIS], active_extruder); | ||||
|             stepper.synchronize(); | ||||
| @@ -9223,23 +9255,6 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) { | ||||
|       switch (dual_x_carriage_mode) { | ||||
|         case DXC_FULL_CONTROL_MODE: | ||||
|           break; | ||||
|         case DXC_DUPLICATION_MODE: | ||||
|           if (active_extruder == 0) { | ||||
|             // move duplicate extruder into correct duplication position. | ||||
|             planner.set_position_mm( | ||||
|               LOGICAL_X_POSITION(inactive_extruder_x_pos), | ||||
|               current_position[Y_AXIS], | ||||
|               current_position[Z_AXIS], | ||||
|               current_position[E_AXIS] | ||||
|             ); | ||||
|             planner.buffer_line(current_position[X_AXIS] + duplicate_extruder_x_offset, | ||||
|                              current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], planner.max_feedrate_mm_s[X_AXIS], 1); | ||||
|             SYNC_PLAN_POSITION_KINEMATIC(); | ||||
|             stepper.synchronize(); | ||||
|             extruder_duplication_enabled = true; | ||||
|             active_extruder_parked = false; | ||||
|           } | ||||
|           break; | ||||
|         case DXC_AUTO_PARK_MODE: | ||||
|           if (current_position[E_AXIS] == destination[E_AXIS]) { | ||||
|             // This is a travel move (with no extrusion) | ||||
| @@ -9252,13 +9267,39 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) { | ||||
|               return false; | ||||
|             } | ||||
|           } | ||||
|           delayed_move_time = 0; | ||||
|           // unpark extruder: 1) raise, 2) move into starting XY position, 3) lower | ||||
|           planner.buffer_line(raised_parked_position[X_AXIS], raised_parked_position[Y_AXIS], raised_parked_position[Z_AXIS], current_position[E_AXIS], planner.max_feedrate_mm_s[Z_AXIS], active_extruder); | ||||
|           planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], raised_parked_position[Z_AXIS], current_position[E_AXIS], PLANNER_XY_FEEDRATE(), active_extruder); | ||||
|           planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], planner.max_feedrate_mm_s[Z_AXIS], active_extruder); | ||||
|           for (uint8_t i = 0; i < 3; i++) | ||||
|             planner.buffer_line( | ||||
|               i == 0 ? raised_parked_position[X_AXIS] : current_position[X_AXIS], | ||||
|               i == 0 ? raised_parked_position[Y_AXIS] : current_position[Y_AXIS], | ||||
|               i == 2 ? current_position[Z_AXIS] : raised_parked_position[Z_AXIS], | ||||
|               current_position[E_AXIS], | ||||
|               i == 1 ? PLANNER_XY_FEEDRATE() : planner.max_feedrate_mm_s[Z_AXIS], | ||||
|               active_extruder | ||||
|             ); | ||||
|           delayed_move_time = 0; | ||||
|           active_extruder_parked = false; | ||||
|           break; | ||||
|         case DXC_DUPLICATION_MODE: | ||||
|           if (active_extruder == 0) { | ||||
|             // move duplicate extruder into correct duplication position. | ||||
|             planner.set_position_mm( | ||||
|               LOGICAL_X_POSITION(inactive_extruder_x_pos), | ||||
|               current_position[Y_AXIS], | ||||
|               current_position[Z_AXIS], | ||||
|               current_position[E_AXIS] | ||||
|             ); | ||||
|             planner.buffer_line( | ||||
|               current_position[X_AXIS] + duplicate_extruder_x_offset, | ||||
|               current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], | ||||
|               planner.max_feedrate_mm_s[X_AXIS], 1 | ||||
|             ); | ||||
|             SYNC_PLAN_POSITION_KINEMATIC(); | ||||
|             stepper.synchronize(); | ||||
|             extruder_duplication_enabled = true; | ||||
|             active_extruder_parked = false; | ||||
|           } | ||||
|           break; | ||||
|       } | ||||
|     } | ||||
|     return true; | ||||
| @@ -9950,7 +9991,7 @@ void kill(const char* lcd_msg) { | ||||
|   disable_all_steppers(); | ||||
|  | ||||
|   #if HAS_POWER_SWITCH | ||||
|     pinMode(PS_ON_PIN, INPUT); | ||||
|     SET_INPUT(PS_ON_PIN); | ||||
|   #endif | ||||
|  | ||||
|   suicide(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user