Wipe tower accounts for extruder offsets

Also, in case of non-single-extruder printer with the wipe tower, first wiping line was printed where the border should have been - fixed
This commit is contained in:
Lukas Matena 2019-07-19 12:59:56 +02:00
parent 2de6d95322
commit eb29c3e01d
4 changed files with 55 additions and 23 deletions

View File

@ -169,6 +169,9 @@ static inline Point wipe_tower_point_to_object_point(GCode &gcodegen, const Vec2
std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::ToolChangeResult &tcr, int new_extruder_id) const std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::ToolChangeResult &tcr, int new_extruder_id) const
{ {
if (new_extruder_id != -1 && new_extruder_id != tcr.new_tool)
throw std::invalid_argument("Error: WipeTowerIntegration::append_tcr was asked to do a toolchange it didn't expect.");
std::string gcode; std::string gcode;
// Toolchangeresult.gcode assumes the wipe tower corner is at the origin // Toolchangeresult.gcode assumes the wipe tower corner is at the origin
@ -182,8 +185,11 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T
end_pos = Eigen::Rotation2Df(alpha) * end_pos; end_pos = Eigen::Rotation2Df(alpha) * end_pos;
end_pos += m_wipe_tower_pos; end_pos += m_wipe_tower_pos;
} }
std::string tcr_rotated_gcode = tcr.priming ? tcr.gcode : rotate_wipe_tower_moves(tcr.gcode, tcr.start_pos, m_wipe_tower_pos, alpha);
Vec2f wipe_tower_offset = tcr.priming ? Vec2f::Zero() : m_wipe_tower_pos;
float wipe_tower_rotation = tcr.priming ? 0.f : alpha;
std::string tcr_rotated_gcode = post_process_wipe_tower_moves(tcr, wipe_tower_offset, wipe_tower_rotation);
// Disable linear advance for the wipe tower operations. // Disable linear advance for the wipe tower operations.
gcode += (gcodegen.config().gcode_flavor == gcfRepRap ? std::string("M572 D0 S0\n") : std::string("M900 K0\n")); gcode += (gcodegen.config().gcode_flavor == gcfRepRap ? std::string("M572 D0 S0\n") : std::string("M900 K0\n"));
@ -285,17 +291,21 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T
// This function postprocesses gcode_original, rotates and moves all G1 extrusions and returns resulting gcode // This function postprocesses gcode_original, rotates and moves all G1 extrusions and returns resulting gcode
// Starting position has to be supplied explicitely (otherwise it would fail in case first G1 command only contained one coordinate) // Starting position has to be supplied explicitely (otherwise it would fail in case first G1 command only contained one coordinate)
std::string WipeTowerIntegration::rotate_wipe_tower_moves(const std::string& gcode_original, const Vec2f& start_pos, const Vec2f& translation, float angle) const std::string WipeTowerIntegration::post_process_wipe_tower_moves(const WipeTower::ToolChangeResult& tcr, const Vec2f& translation, float angle) const
{ {
std::istringstream gcode_str(gcode_original); Vec2f extruder_offset = m_extruder_offsets[tcr.initial_tool].cast<float>();
std::istringstream gcode_str(tcr.gcode);
std::string gcode_out; std::string gcode_out;
std::string line; std::string line;
Vec2f pos = start_pos; Vec2f pos = tcr.start_pos;
Vec2f transformed_pos; Vec2f transformed_pos = pos;
Vec2f old_pos(-1000.1f, -1000.1f); Vec2f old_pos(-1000.1f, -1000.1f);
while (gcode_str) { while (gcode_str) {
std::getline(gcode_str, line); // we read the gcode line by line std::getline(gcode_str, line); // we read the gcode line by line
// All G1 commands should be translated and rotated
if (line.find("G1 ") == 0) { if (line.find("G1 ") == 0) {
std::ostringstream line_out; std::ostringstream line_out;
std::istringstream line_str(line); std::istringstream line_str(line);
@ -317,17 +327,34 @@ std::string WipeTowerIntegration::rotate_wipe_tower_moves(const std::string& gco
if (transformed_pos != old_pos) { if (transformed_pos != old_pos) {
line = line_out.str(); line = line_out.str();
char buf[2048] = "G1"; std::ostringstream oss;
oss << std::fixed << std::setprecision(3) << "G1 ";
if (transformed_pos.x() != old_pos.x()) if (transformed_pos.x() != old_pos.x())
sprintf(buf + strlen(buf), " X%.3f", transformed_pos.x()); oss << " X" << transformed_pos.x() - extruder_offset.x();
if (transformed_pos.y() != old_pos.y()) if (transformed_pos.y() != old_pos.y())
sprintf(buf + strlen(buf), " Y%.3f", transformed_pos.y()); oss << " Y" << transformed_pos.y() - extruder_offset.y();
line.replace(line.find("G1 "), 3, buf); line.replace(line.find("G1 "), 3, oss.str());
old_pos = transformed_pos; old_pos = transformed_pos;
} }
} }
gcode_out += line + "\n"; gcode_out += line + "\n";
// If this was a toolchange command, we should change current extruder offset
if (line == "[toolchange_gcode]") {
extruder_offset = m_extruder_offsets[tcr.new_tool].cast<float>();
// If the extruder offset changed, add an extra move so everything is continuous
if (extruder_offset != m_extruder_offsets[tcr.initial_tool].cast<float>()) {
std::ostringstream oss;
oss << std::fixed << std::setprecision(3)
<< "G1 X" << transformed_pos.x() - extruder_offset.x()
<< " Y" << transformed_pos.y() - extruder_offset.y()
<< "\n";
gcode_out += oss.str();
}
}
} }
return gcode_out; return gcode_out;
} }

View File

@ -90,6 +90,7 @@ public:
m_right(float(/*print_config.wipe_tower_x.value +*/ print_config.wipe_tower_width.value)), m_right(float(/*print_config.wipe_tower_x.value +*/ print_config.wipe_tower_width.value)),
m_wipe_tower_pos(float(print_config.wipe_tower_x.value), float(print_config.wipe_tower_y.value)), m_wipe_tower_pos(float(print_config.wipe_tower_x.value), float(print_config.wipe_tower_y.value)),
m_wipe_tower_rotation(float(print_config.wipe_tower_rotation_angle)), m_wipe_tower_rotation(float(print_config.wipe_tower_rotation_angle)),
m_extruder_offsets(print_config.extruder_offset.values),
m_priming(priming), m_priming(priming),
m_tool_changes(tool_changes), m_tool_changes(tool_changes),
m_final_purge(final_purge), m_final_purge(final_purge),
@ -107,14 +108,16 @@ private:
WipeTowerIntegration& operator=(const WipeTowerIntegration&); WipeTowerIntegration& operator=(const WipeTowerIntegration&);
std::string append_tcr(GCode &gcodegen, const WipeTower::ToolChangeResult &tcr, int new_extruder_id) const; std::string append_tcr(GCode &gcodegen, const WipeTower::ToolChangeResult &tcr, int new_extruder_id) const;
// Postprocesses gcode: rotates and moves all G1 extrusions and returns result // Postprocesses gcode: rotates and moves G1 extrusions and returns result
std::string rotate_wipe_tower_moves(const std::string& gcode_original, const Vec2f& start_pos, const Vec2f& translation, float angle) const; std::string post_process_wipe_tower_moves(const WipeTower::ToolChangeResult& tcr, const Vec2f& translation, float angle) const;
// Left / right edges of the wipe tower, for the planning of wipe moves. // Left / right edges of the wipe tower, for the planning of wipe moves.
const float m_left; const float m_left;
const float m_right; const float m_right;
const Vec2f m_wipe_tower_pos; const Vec2f m_wipe_tower_pos;
const float m_wipe_tower_rotation; const float m_wipe_tower_rotation;
const std::vector<Vec2d> m_extruder_offsets;
// Reference to cached values at the Printer class. // Reference to cached values at the Printer class.
const std::vector<WipeTower::ToolChangeResult> &m_priming; const std::vector<WipeTower::ToolChangeResult> &m_priming;
const std::vector<std::vector<WipeTower::ToolChangeResult>> &m_tool_changes; const std::vector<std::vector<WipeTower::ToolChangeResult>> &m_tool_changes;

View File

@ -553,7 +553,7 @@ std::vector<WipeTower::ToolChangeResult> WipeTower::prime(
result.elapsed_time = writer.elapsed_time(); result.elapsed_time = writer.elapsed_time();
result.extrusions = writer.extrusions(); result.extrusions = writer.extrusions();
result.start_pos = writer.start_pos_rotated(); result.start_pos = writer.start_pos_rotated();
result.end_pos = writer.pos_rotated(); result.end_pos = writer.pos();
results.push_back(std::move(result)); results.push_back(std::move(result));

View File

@ -139,13 +139,15 @@ public:
m_perimeter_width = nozzle_diameter * Width_To_Nozzle_Ratio; // all extruders are now assumed to have the same diameter m_perimeter_width = nozzle_diameter * Width_To_Nozzle_Ratio; // all extruders are now assumed to have the same diameter
std::stringstream stream{m_semm ? ramming_parameters : std::string()}; if (m_semm) {
std::stringstream stream{ramming_parameters};
float speed = 0.f; float speed = 0.f;
stream >> m_filpar[idx].ramming_line_width_multiplicator >> m_filpar[idx].ramming_step_multiplicator; stream >> m_filpar[idx].ramming_line_width_multiplicator >> m_filpar[idx].ramming_step_multiplicator;
m_filpar[idx].ramming_line_width_multiplicator /= 100; m_filpar[idx].ramming_line_width_multiplicator /= 100;
m_filpar[idx].ramming_step_multiplicator /= 100; m_filpar[idx].ramming_step_multiplicator /= 100;
while (stream >> speed) while (stream >> speed)
m_filpar[idx].ramming_speed.push_back(speed); m_filpar[idx].ramming_speed.push_back(speed);
}
m_used_filament_length.resize(std::max(m_used_filament_length.size(), idx + 1)); // makes sure that the vector is big enough so we don't have to check later m_used_filament_length.resize(std::max(m_used_filament_length.size(), idx + 1)); // makes sure that the vector is big enough so we don't have to check later
} }
@ -241,8 +243,8 @@ public:
int cooling_moves = 0; int cooling_moves = 0;
float cooling_initial_speed = 0.f; float cooling_initial_speed = 0.f;
float cooling_final_speed = 0.f; float cooling_final_speed = 0.f;
float ramming_line_width_multiplicator = 0.f; float ramming_line_width_multiplicator = 1.f;
float ramming_step_multiplicator = 0.f; float ramming_step_multiplicator = 1.f;
float max_e_speed = std::numeric_limits<float>::max(); float max_e_speed = std::numeric_limits<float>::max();
std::vector<float> ramming_speed; std::vector<float> ramming_speed;
float nozzle_diameter; float nozzle_diameter;