Skip to content

Commit

Permalink
[FEATURE] Klipper accel to decel support
Browse files Browse the repository at this point in the history
  • Loading branch information
mjonuschat committed Apr 6, 2024
1 parent 7763bda commit 39d20ba
Show file tree
Hide file tree
Showing 11 changed files with 356 additions and 131 deletions.
61 changes: 46 additions & 15 deletions src/libslic3r/GCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2990,9 +2990,13 @@ std::string GCodeGenerator::extrude_loop(const ExtrusionLoop &loop_src, const GC
gcode += this->_extrude(el.path_attributes, el.path, description, speed);

// reset acceleration
gcode += m_writer.set_print_acceleration(fast_round_up<unsigned int>(m_config.default_acceleration.value));
gcode += m_writer.set_print_acceleration(
fast_round_up<unsigned int>(m_config.default_acceleration.value),
fast_round_up<unsigned int>(m_config.default_accel_to_decel.value),
"Default"
);
//reset jerk
gcode += m_writer.set_jerk(fast_round_up<unsigned int>(m_config.default_jerk.value));
gcode += m_writer.set_jerk(fast_round_up<unsigned int>(m_config.default_jerk.value), "Default");

if (m_wipe.enabled()) {
// Wipe will hide the seam.
Expand Down Expand Up @@ -3040,9 +3044,13 @@ std::string GCodeGenerator::extrude_skirt(
}

// reset acceleration
gcode += m_writer.set_print_acceleration(fast_round_up<unsigned int>(m_config.default_acceleration.value));
gcode += m_writer.set_print_acceleration(
fast_round_up<unsigned int>(m_config.default_acceleration.value),
fast_round_up<unsigned int>(m_config.default_accel_to_decel.value),
"Default"
);
// reset jerk
gcode += m_writer.set_jerk(fast_round_up<unsigned int>(m_config.default_jerk.value));
gcode += m_writer.set_jerk(fast_round_up<unsigned int>(m_config.default_jerk.value), "Default");

if (m_wipe.enabled())
// Wipe will hide the seam.
Expand Down Expand Up @@ -3070,9 +3078,13 @@ std::string GCodeGenerator::extrude_multi_path(const ExtrusionMultiPath &multipa
m_wipe.set_path(std::move(smooth_path));

// reset acceleration
gcode += m_writer.set_print_acceleration((unsigned int)floor(m_config.default_acceleration.value + 0.5));
gcode += m_writer.set_print_acceleration(
fast_round_up<unsigned int>(m_config.default_acceleration.value),
fast_round_up<unsigned int>(m_config.default_accel_to_decel.value),
"Default"
);
// reset jerk
gcode += m_writer.set_jerk(m_config.default_jerk.value);
gcode += m_writer.set_jerk(m_config.default_jerk.value, "Default");
return gcode;
}

Expand All @@ -3096,9 +3108,13 @@ std::string GCodeGenerator::extrude_path(const ExtrusionPath &path, bool reverse
Geometry::ArcWelder::reverse(smooth_path);
m_wipe.set_path(std::move(smooth_path));
// reset acceleration
gcode += m_writer.set_print_acceleration((unsigned int)floor(m_config.default_acceleration.value + 0.5));
gcode += m_writer.set_print_acceleration(
fast_round_up<unsigned int>(m_config.default_acceleration.value),
fast_round_up<unsigned int>(m_config.default_accel_to_decel.value),
"Default"
);
// reset jerk
gcode += m_writer.set_jerk(m_config.default_jerk.value);
gcode += m_writer.set_jerk(m_config.default_jerk.value, "Default");
return gcode;
}

Expand Down Expand Up @@ -3333,26 +3349,40 @@ std::string GCodeGenerator::_extrude(
// adjust acceleration
if (m_config.default_acceleration.value > 0) {
double acceleration;
double accel_to_decel;
if (this->on_first_layer() && m_config.first_layer_acceleration.value > 0) {
acceleration = m_config.first_layer_acceleration.value;
accel_to_decel = m_config.first_layer_accel_to_decel.value;
} else if (this->object_layer_over_raft() && m_config.first_layer_acceleration_over_raft.value > 0) {
acceleration = m_config.first_layer_acceleration_over_raft.value;
accel_to_decel = m_config.first_layer_accel_to_decel_over_raft.value;
} else if (m_config.bridge_acceleration.value > 0 && path_attr.role.is_bridge()) {
acceleration = m_config.bridge_acceleration.value;
accel_to_decel = m_config.bridge_accel_to_decel.value;
} else if (m_config.top_solid_infill_acceleration > 0 && path_attr.role == ExtrusionRole::TopSolidInfill) {
acceleration = m_config.top_solid_infill_acceleration.value;
accel_to_decel = m_config.top_solid_infill_accel_to_decel.value;
} else if (m_config.solid_infill_acceleration > 0 && path_attr.role.is_solid_infill()) {
acceleration = m_config.solid_infill_acceleration.value;
accel_to_decel = m_config.solid_infill_accel_to_decel.value;
} else if (m_config.infill_acceleration.value > 0 && path_attr.role.is_infill()) {
acceleration = m_config.infill_acceleration.value;
accel_to_decel = m_config.infill_accel_to_decel.value;
} else if (m_config.external_perimeter_acceleration > 0 && path_attr.role.is_external_perimeter()) {
acceleration = m_config.external_perimeter_acceleration.value;
accel_to_decel = m_config.external_perimeter_accel_to_decel.value;
} else if (m_config.perimeter_acceleration.value > 0 && path_attr.role.is_perimeter()) {
acceleration = m_config.perimeter_acceleration.value;
accel_to_decel = m_config.perimeter_accel_to_decel.value;
} else {
acceleration = m_config.default_acceleration.value;
accel_to_decel = m_config.default_accel_to_decel.value;
}
gcode += m_writer.set_print_acceleration((unsigned int)floor(acceleration + 0.5));
gcode += m_writer.set_print_acceleration(
fast_round_up<unsigned int>(acceleration),
fast_round_up<unsigned int>(accel_to_decel),
gcode_extrusion_role_to_string(extrusion_role_to_gcode_extrusion_role(path_attr.role))
);
}

// adjust jerk
Expand All @@ -3377,7 +3407,7 @@ std::string GCodeGenerator::_extrude(
} else {
jerk = m_config.default_jerk.value;
}
gcode += m_writer.set_jerk(jerk);
gcode += m_writer.set_jerk(jerk, gcode_extrusion_role_to_string(extrusion_role_to_gcode_extrusion_role(path_attr.role)));
}

// calculate extrusion length per distance unit
Expand Down Expand Up @@ -3586,17 +3616,18 @@ std::string GCodeGenerator::generate_travel_gcode(
) {
std::string gcode;

const unsigned acceleration =(unsigned)(m_config.travel_acceleration.value + 0.5);
const unsigned acceleration = fast_round_up<unsigned int>(m_config.travel_acceleration.value);
const unsigned accel_to_decel = fast_round_up<unsigned int>(m_config.travel_accel_to_decel.value);

if (travel.empty()) {
return "";
}

// generate G-code for the travel move
// use G1 because we rely on paths being straight (G0 may make round paths)
gcode += this->m_writer.set_travel_acceleration(acceleration);
gcode += this->m_writer.set_travel_acceleration(acceleration, accel_to_decel);
if (m_config.default_jerk > 0 && m_config.travel_jerk > 0)
gcode += this->m_writer.set_jerk(m_config.travel_jerk);
gcode += this->m_writer.set_jerk(m_config.travel_jerk, "Travel");

Vec3d previous_point{this->point_to_gcode(travel.front())};
bool already_inserted{false};
Expand All @@ -3617,11 +3648,11 @@ std::string GCodeGenerator::generate_travel_gcode(
if (! GCodeWriter::supports_separate_travel_acceleration(config().gcode_flavor)) {
// In case that this flavor does not support separate print and travel acceleration,
// reset acceleration to default.
gcode += this->m_writer.set_travel_acceleration(acceleration);
gcode += this->m_writer.set_print_acceleration(m_config.default_acceleration, m_config.default_accel_to_decel, "Default");
}

if (m_config.default_jerk > 0 && m_config.travel_jerk > 0)
gcode += this->m_writer.set_jerk(m_config.default_jerk);
gcode += this->m_writer.set_jerk(m_config.default_jerk, "Default");
return gcode;
}

Expand Down
37 changes: 28 additions & 9 deletions src/libslic3r/GCode/GCodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ void GCodeWriter::apply_print_config(const PrintConfig &print_config)
print_config.machine_max_jerk_x.values.front() : 0));
m_max_jerk_y = static_cast<unsigned int>(std::round((use_mach_limits && print_config.machine_limits_usage.value == MachineLimitsUsage::EmitToGCode) ?
print_config.machine_max_jerk_y.values.front() : 0));

m_max_accel_to_decel = static_cast<unsigned int>(std::round((use_mach_limits && print_config.machine_limits_usage.value == MachineLimitsUsage::EmitToGCode) ?
print_config.machine_max_acceleration_extruding.values.front() : 0));
}

void GCodeWriter::set_extruders(std::vector<unsigned int> extruder_ids)
Expand Down Expand Up @@ -186,38 +189,50 @@ std::string GCodeWriter::set_bed_temperature(unsigned int temperature, bool wait
return gcode.str();
}

std::string GCodeWriter::set_acceleration_internal(Acceleration type, unsigned int acceleration)
std::string GCodeWriter::set_acceleration_internal(Acceleration type, unsigned int acceleration, unsigned int accel_to_decel, const std::string_view comment)
{
// Clamp the acceleration to the allowed maximum.
if (type == Acceleration::Print && m_max_acceleration > 0 && acceleration > m_max_acceleration)
acceleration = m_max_acceleration;
if (type == Acceleration::Travel && m_max_travel_acceleration > 0 && acceleration > m_max_travel_acceleration)
acceleration = m_max_travel_acceleration;

// Clamp the accel_to_decel to the allowed maximum.
if (m_max_accel_to_decel > 0 && accel_to_decel > m_max_accel_to_decel)
accel_to_decel = m_max_accel_to_decel;

// Are we setting travel acceleration for a flavour that supports separate travel and print acc?
bool separate_travel = (type == Acceleration::Travel && supports_separate_travel_acceleration(this->config.gcode_flavor));

auto& last_value = separate_travel ? m_last_travel_acceleration : m_last_acceleration ;
if (acceleration == 0 || acceleration == last_value)
auto& last_acceleration_value = separate_travel ? m_last_travel_acceleration : m_last_acceleration ;
auto& last_accel_to_decel_value = m_last_accel_to_decel;
if ((acceleration == 0 || acceleration == last_acceleration_value) && (accel_to_decel == 0 || accel_to_decel == last_accel_to_decel_value))
return {};

last_value = acceleration;
last_acceleration_value = acceleration;
last_accel_to_decel_value = accel_to_decel;

std::ostringstream gcode;
if (FLAVOR_IS(gcfRepetier))
if (FLAVOR_IS(gcfKlipper)) {
gcode << "SET_VELOCITY_LIMIT ACCEL=" << acceleration;
if (accel_to_decel > 0)
gcode << " ACCEL_TO_DECEL=" << accel_to_decel;
} else if (FLAVOR_IS(gcfRepetier))
gcode << (separate_travel ? "M202 X" : "M201 X") << acceleration << " Y" << acceleration;
else if (FLAVOR_IS(gcfRepRapFirmware) || FLAVOR_IS(gcfMarlinFirmware))
gcode << (separate_travel ? "M204 T" : "M204 P") << acceleration;
else
gcode << "M204 S" << acceleration;

if (this->config.gcode_comments) gcode << " ; adjust acceleration";
if (this->config.gcode_comments)
gcode << " ; adjust acceleration (" << comment << ")";

gcode << "\n";

return gcode.str();
}

std::string GCodeWriter::set_jerk(unsigned int jerk)
std::string GCodeWriter::set_jerk(unsigned int jerk, const std::string_view comment)
{
if (jerk == 0 || jerk == m_last_jerk)
return {};
Expand All @@ -232,12 +247,16 @@ std::string GCodeWriter::set_jerk(unsigned int jerk)
m_last_jerk = jerk;

std::ostringstream gcode;
if (FLAVOR_IS(gcfRepRapFirmware))
if (FLAVOR_IS(gcfKlipper))
gcode << "SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY=" << jerk;
else if (FLAVOR_IS(gcfRepRapFirmware))
gcode << "M566 X" << jerk_x << " Y" << jerk_y;
else
gcode << "M205 X" << jerk_x << " Y" << jerk_y;

if (this->config.gcode_comments) gcode << " ; adjust jerk";
if (this->config.gcode_comments)
gcode << " ; adjust jerk (" << comment << ")";

gcode << "\n";

return gcode.str();
Expand Down
13 changes: 8 additions & 5 deletions src/libslic3r/GCode/GCodeWriter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "../Point.hpp"
#include "../PrintConfig.hpp"
#include "CoolingBuffer.hpp"
#include "libslic3r/ExtrusionRole.hpp"

#include <string>
#include <string_view>
Expand All @@ -29,7 +30,7 @@ class GCodeWriter {
GCodeWriter() :
multiple_extruders(false), m_extrusion_axis("E"), m_extruder(nullptr),
m_single_extruder_multi_material(false),
m_last_acceleration(0), m_max_acceleration(0), m_last_jerk(0),
m_last_acceleration(0), m_max_acceleration(0), m_max_accel_to_decel(0), m_last_jerk(0),
m_last_bed_temperature(0), m_last_bed_temperature_reached(true)
{}
Extruder* extruder() { return m_extruder; }
Expand All @@ -52,9 +53,9 @@ class GCodeWriter {
std::string postamble() const;
std::string set_temperature(unsigned int temperature, bool wait = false, int tool = -1) const;
std::string set_bed_temperature(unsigned int temperature, bool wait = false);
std::string set_print_acceleration(unsigned int acceleration) { return set_acceleration_internal(Acceleration::Print, acceleration); }
std::string set_travel_acceleration(unsigned int acceleration) { return set_acceleration_internal(Acceleration::Travel, acceleration); }
std::string set_jerk(unsigned int jerk);
std::string set_print_acceleration(unsigned int acceleration, unsigned int accel_to_decel, const std::string_view comment) { return set_acceleration_internal(Acceleration::Print, acceleration, accel_to_decel, comment); }
std::string set_travel_acceleration(unsigned int acceleration, unsigned int accel_to_decel) { return set_acceleration_internal(Acceleration::Travel, acceleration, accel_to_decel, "Travel"); }
std::string set_jerk(unsigned int jerk, const std::string_view comment);
std::string reset_e(bool force = false);
std::string update_progress(unsigned int num, unsigned int tot, bool allow_100 = false) const;
// return false if this extruder was already selected
Expand Down Expand Up @@ -120,11 +121,13 @@ class GCodeWriter {
bool m_single_extruder_multi_material;
Extruder* m_extruder;
unsigned int m_last_acceleration = (unsigned int)(-1);
unsigned int m_last_accel_to_decel = (unsigned int)(-1);
unsigned int m_last_travel_acceleration = (unsigned int)(-1); // only used for flavors supporting separate print/travel acc
// Limit for setting the acceleration, to respect the machine limits set for the Marlin firmware.
// If set to zero, the limit is not in action.
unsigned int m_max_acceleration;
unsigned int m_max_travel_acceleration;
unsigned int m_max_accel_to_decel;

unsigned int m_last_jerk = (unsigned int)(-1);
unsigned int m_max_jerk_x;
Expand All @@ -140,7 +143,7 @@ class GCodeWriter {
};

std::string _retract(double length, double restart_extra, const std::string_view comment);
std::string set_acceleration_internal(Acceleration type, unsigned int acceleration);
std::string set_acceleration_internal(Acceleration type, unsigned int acceleration, unsigned int accel_to_decel, const std::string_view comment);
};

class GCodeFormatter {
Expand Down
16 changes: 12 additions & 4 deletions src/libslic3r/GCode/WipeTowerIntegration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,20 @@ std::string WipeTowerIntegration::append_tcr(GCodeGenerator &gcodegen, const Wip
unescape_string_cstyle(tcr_rotated_gcode, tcr_gcode);

if (gcodegen.config().default_acceleration > 0) {
gcode += gcodegen.writer().set_print_acceleration(fast_round_up<unsigned int>(gcodegen.config().wipe_tower_acceleration.value));
gcode += gcodegen.writer().set_jerk(fast_round_up<unsigned int>(gcodegen.config().wipe_tower_jerk.value));
gcode += gcodegen.writer().set_print_acceleration(
fast_round_up<unsigned int>(gcodegen.config().wipe_tower_acceleration.value),
fast_round_up<unsigned int>(gcodegen.config().wipe_tower_accel_to_decel.value),
"Wipe Tower"
);
gcode += gcodegen.writer().set_jerk(fast_round_up<unsigned int>(gcodegen.config().wipe_tower_jerk.value), "Wipe Tower");
}
gcode += tcr_gcode;
gcode += gcodegen.writer().set_print_acceleration(fast_round_up<unsigned int>(gcodegen.config().default_acceleration.value));
gcode += gcodegen.writer().set_jerk(fast_round_up<unsigned int>(gcodegen.config().default_jerk.value));
gcode += gcodegen.writer().set_print_acceleration(
fast_round_up<unsigned int>(gcodegen.config().default_acceleration.value),
fast_round_up<unsigned int>(gcodegen.config().default_accel_to_decel.value),
"Default"
);
gcode += gcodegen.writer().set_jerk(fast_round_up<unsigned int>(gcodegen.config().default_jerk.value), "Default");
// A phony move to the end position at the wipe tower.
gcodegen.writer().travel_to_xy(end_pos.cast<double>());
gcodegen.last_position = wipe_tower_point_to_object_point(gcodegen, end_pos);
Expand Down
Loading

0 comments on commit 39d20ba

Please sign in to comment.