Skip to content

Commit 47926df

Browse files
committed
[FEATURE] Klipper accel to decel support
1 parent aef9c82 commit 47926df

File tree

10 files changed

+275
-71
lines changed

10 files changed

+275
-71
lines changed

src/libslic3r/GCode.cpp

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2863,9 +2863,13 @@ std::string GCodeGenerator::extrude_loop(const ExtrusionLoop &loop_src, const GC
28632863
gcode += this->_extrude(el.path_attributes, el.path, description, speed);
28642864

28652865
// reset acceleration
2866-
gcode += m_writer.set_print_acceleration(fast_round_up<unsigned int>(m_config.default_acceleration.value));
2866+
gcode += m_writer.set_print_acceleration(
2867+
fast_round_up<unsigned int>(m_config.default_acceleration.value),
2868+
fast_round_up<unsigned int>(m_config.default_accel_to_decel.value),
2869+
"Default"
2870+
);
28672871
//reset jerk
2868-
gcode += m_writer.set_jerk(fast_round_up<unsigned int>(m_config.default_jerk.value));
2872+
gcode += m_writer.set_jerk(fast_round_up<unsigned int>(m_config.default_jerk.value), "Default");
28692873

28702874
if (m_wipe.enabled()) {
28712875
// Wipe will hide the seam.
@@ -2913,9 +2917,13 @@ std::string GCodeGenerator::extrude_skirt(
29132917
}
29142918

29152919
// reset acceleration
2916-
gcode += m_writer.set_print_acceleration(fast_round_up<unsigned int>(m_config.default_acceleration.value));
2920+
gcode += m_writer.set_print_acceleration(
2921+
fast_round_up<unsigned int>(m_config.default_acceleration.value),
2922+
fast_round_up<unsigned int>(m_config.default_accel_to_decel.value),
2923+
"Default"
2924+
);
29172925
// reset jerk
2918-
gcode += m_writer.set_jerk(fast_round_up<unsigned int>(m_config.default_jerk.value));
2926+
gcode += m_writer.set_jerk(fast_round_up<unsigned int>(m_config.default_jerk.value), "Default");
29192927

29202928
if (m_wipe.enabled())
29212929
// Wipe will hide the seam.
@@ -2940,9 +2948,13 @@ std::string GCodeGenerator::extrude_multi_path(const ExtrusionMultiPath &multipa
29402948
gcode += this->_extrude(el.path_attributes, el.path, description, speed);
29412949
m_wipe.set_path(std::move(smooth_path), true);
29422950
// reset acceleration
2943-
gcode += m_writer.set_print_acceleration((unsigned int)floor(m_config.default_acceleration.value + 0.5));
2951+
gcode += m_writer.set_print_acceleration(
2952+
fast_round_up<unsigned int>(m_config.default_acceleration.value),
2953+
fast_round_up<unsigned int>(m_config.default_accel_to_decel.value),
2954+
"Default"
2955+
);
29442956
// reset jerk
2945-
gcode += m_writer.set_jerk(m_config.default_jerk.value);
2957+
gcode += m_writer.set_jerk(m_config.default_jerk.value, "Default");
29462958
return gcode;
29472959
}
29482960

@@ -2966,9 +2978,13 @@ std::string GCodeGenerator::extrude_path(const ExtrusionPath &path, bool reverse
29662978
Geometry::ArcWelder::reverse(smooth_path);
29672979
m_wipe.set_path(std::move(smooth_path));
29682980
// reset acceleration
2969-
gcode += m_writer.set_print_acceleration((unsigned int)floor(m_config.default_acceleration.value + 0.5));
2981+
gcode += m_writer.set_print_acceleration(
2982+
fast_round_up<unsigned int>(m_config.default_acceleration.value),
2983+
fast_round_up<unsigned int>(m_config.default_accel_to_decel.value),
2984+
"Default"
2985+
);
29702986
// reset jerk
2971-
gcode += m_writer.set_jerk(m_config.default_jerk.value);
2987+
gcode += m_writer.set_jerk(m_config.default_jerk.value, "Default");
29722988
return gcode;
29732989
}
29742990

@@ -3168,26 +3184,40 @@ std::string GCodeGenerator::_extrude(
31683184
// adjust acceleration
31693185
if (m_config.default_acceleration.value > 0) {
31703186
double acceleration;
3187+
double accel_to_decel;
31713188
if (this->on_first_layer() && m_config.first_layer_acceleration.value > 0) {
31723189
acceleration = m_config.first_layer_acceleration.value;
3190+
accel_to_decel = m_config.first_layer_accel_to_decel.value;
31733191
} else if (this->object_layer_over_raft() && m_config.first_layer_acceleration_over_raft.value > 0) {
31743192
acceleration = m_config.first_layer_acceleration_over_raft.value;
3193+
accel_to_decel = m_config.first_layer_accel_to_decel_over_raft.value;
31753194
} else if (m_config.bridge_acceleration.value > 0 && path_attr.role.is_bridge()) {
31763195
acceleration = m_config.bridge_acceleration.value;
3196+
accel_to_decel = m_config.bridge_accel_to_decel.value;
31773197
} else if (m_config.top_solid_infill_acceleration > 0 && path_attr.role == ExtrusionRole::TopSolidInfill) {
31783198
acceleration = m_config.top_solid_infill_acceleration.value;
3199+
accel_to_decel = m_config.top_solid_infill_accel_to_decel.value;
31793200
} else if (m_config.solid_infill_acceleration > 0 && path_attr.role.is_solid_infill()) {
31803201
acceleration = m_config.solid_infill_acceleration.value;
3202+
accel_to_decel = m_config.solid_infill_accel_to_decel.value;
31813203
} else if (m_config.infill_acceleration.value > 0 && path_attr.role.is_infill()) {
31823204
acceleration = m_config.infill_acceleration.value;
3205+
accel_to_decel = m_config.infill_accel_to_decel.value;
31833206
} else if (m_config.external_perimeter_acceleration > 0 && path_attr.role.is_external_perimeter()) {
31843207
acceleration = m_config.external_perimeter_acceleration.value;
3208+
accel_to_decel = m_config.external_perimeter_accel_to_decel.value;
31853209
} else if (m_config.perimeter_acceleration.value > 0 && path_attr.role.is_perimeter()) {
31863210
acceleration = m_config.perimeter_acceleration.value;
3211+
accel_to_decel = m_config.perimeter_accel_to_decel.value;
31873212
} else {
31883213
acceleration = m_config.default_acceleration.value;
3214+
accel_to_decel = m_config.default_accel_to_decel.value;
31893215
}
3190-
gcode += m_writer.set_print_acceleration((unsigned int)floor(acceleration + 0.5));
3216+
gcode += m_writer.set_print_acceleration(
3217+
fast_round_up<unsigned int>(acceleration),
3218+
fast_round_up<unsigned int>(accel_to_decel),
3219+
gcode_extrusion_role_to_string(extrusion_role_to_gcode_extrusion_role(path_attr.role))
3220+
);
31913221
}
31923222

31933223
// adjust jerk
@@ -3212,7 +3242,7 @@ std::string GCodeGenerator::_extrude(
32123242
} else {
32133243
jerk = m_config.default_jerk.value;
32143244
}
3215-
gcode += m_writer.set_jerk(jerk);
3245+
gcode += m_writer.set_jerk(jerk, gcode_extrusion_role_to_string(extrusion_role_to_gcode_extrusion_role(path_attr.role)));
32163246
}
32173247

32183248
// calculate extrusion length per distance unit
@@ -3420,17 +3450,18 @@ std::string GCodeGenerator::generate_travel_gcode(
34203450
) {
34213451
std::string gcode;
34223452

3423-
const unsigned acceleration =(unsigned)(m_config.travel_acceleration.value + 0.5);
3453+
const unsigned acceleration = fast_round_up<unsigned int>(m_config.travel_acceleration.value);
3454+
const unsigned accel_to_decel = fast_round_up<unsigned int>(m_config.travel_accel_to_decel.value);
34243455

34253456
if (travel.empty()) {
34263457
return "";
34273458
}
34283459

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

34353466
Vec3d previous_point{this->point_to_gcode(travel.front())};
34363467
for (const Vec3crd& point : travel) {
@@ -3444,11 +3475,11 @@ std::string GCodeGenerator::generate_travel_gcode(
34443475
if (! GCodeWriter::supports_separate_travel_acceleration(config().gcode_flavor)) {
34453476
// In case that this flavor does not support separate print and travel acceleration,
34463477
// reset acceleration to default.
3447-
gcode += this->m_writer.set_travel_acceleration(acceleration);
3478+
gcode += this->m_writer.set_print_acceleration(m_config.default_acceleration, m_config.default_accel_to_decel, "Default");
34483479
}
34493480

34503481
if (m_config.default_jerk > 0 && m_config.travel_jerk > 0)
3451-
gcode += this->m_writer.set_jerk(m_config.default_jerk);
3482+
gcode += this->m_writer.set_jerk(m_config.default_jerk, "Default");
34523483
return gcode;
34533484
}
34543485

src/libslic3r/GCode/GCodeWriter.cpp

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ void GCodeWriter::apply_print_config(const PrintConfig &print_config)
5656
print_config.machine_max_jerk_x.values.front() : 0));
5757
m_max_jerk_y = static_cast<unsigned int>(std::round((use_mach_limits && print_config.machine_limits_usage.value == MachineLimitsUsage::EmitToGCode) ?
5858
print_config.machine_max_jerk_y.values.front() : 0));
59+
60+
m_max_accel_to_decel = static_cast<unsigned int>(std::round((use_mach_limits && print_config.machine_limits_usage.value == MachineLimitsUsage::EmitToGCode) ?
61+
print_config.machine_max_acceleration_extruding.values.front() : 0));
5962
}
6063

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

189-
std::string GCodeWriter::set_acceleration_internal(Acceleration type, unsigned int acceleration)
192+
std::string GCodeWriter::set_acceleration_internal(Acceleration type, unsigned int acceleration, unsigned int accel_to_decel, const std::string_view comment)
190193
{
191194
// Clamp the acceleration to the allowed maximum.
192195
if (type == Acceleration::Print && m_max_acceleration > 0 && acceleration > m_max_acceleration)
193196
acceleration = m_max_acceleration;
194197
if (type == Acceleration::Travel && m_max_travel_acceleration > 0 && acceleration > m_max_travel_acceleration)
195198
acceleration = m_max_travel_acceleration;
196199

200+
// Clamp the accel_to_decel to the allowed maximum.
201+
if (m_max_accel_to_decel > 0 && accel_to_decel > m_max_accel_to_decel)
202+
accel_to_decel = m_max_accel_to_decel;
203+
197204
// Are we setting travel acceleration for a flavour that supports separate travel and print acc?
198205
bool separate_travel = (type == Acceleration::Travel && supports_separate_travel_acceleration(this->config.gcode_flavor));
199206

200-
auto& last_value = separate_travel ? m_last_travel_acceleration : m_last_acceleration ;
201-
if (acceleration == 0 || acceleration == last_value)
207+
auto& last_acceleration_value = separate_travel ? m_last_travel_acceleration : m_last_acceleration ;
208+
auto& last_accel_to_decel_value = m_last_accel_to_decel;
209+
if ((acceleration == 0 || acceleration == last_acceleration_value) && (accel_to_decel == 0 || accel_to_decel == last_accel_to_decel_value))
202210
return {};
203211

204-
last_value = acceleration;
212+
last_acceleration_value = acceleration;
213+
last_accel_to_decel_value = accel_to_decel;
205214

206215
std::ostringstream gcode;
207-
if (FLAVOR_IS(gcfRepetier))
216+
if (FLAVOR_IS(gcfKlipper)) {
217+
gcode << "SET_VELOCITY_LIMIT ACCEL=" << acceleration;
218+
if (accel_to_decel > 0)
219+
gcode << " ACCEL_TO_DECEL=" << accel_to_decel;
220+
} else if (FLAVOR_IS(gcfRepetier))
208221
gcode << (separate_travel ? "M202 X" : "M201 X") << acceleration << " Y" << acceleration;
209222
else if (FLAVOR_IS(gcfRepRapFirmware) || FLAVOR_IS(gcfMarlinFirmware))
210223
gcode << (separate_travel ? "M204 T" : "M204 P") << acceleration;
211224
else
212225
gcode << "M204 S" << acceleration;
213226

214-
if (this->config.gcode_comments) gcode << " ; adjust acceleration";
227+
if (this->config.gcode_comments)
228+
gcode << " ; adjust acceleration (" << comment << ")";
229+
215230
gcode << "\n";
216231

217232
return gcode.str();
218233
}
219234

220-
std::string GCodeWriter::set_jerk(unsigned int jerk)
235+
std::string GCodeWriter::set_jerk(unsigned int jerk, const std::string_view comment)
221236
{
222237
if (jerk == 0 || jerk == m_last_jerk)
223238
return {};
@@ -232,12 +247,16 @@ std::string GCodeWriter::set_jerk(unsigned int jerk)
232247
m_last_jerk = jerk;
233248

234249
std::ostringstream gcode;
235-
if (FLAVOR_IS(gcfRepRapFirmware))
250+
if (FLAVOR_IS(gcfKlipper))
251+
gcode << "SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY=" << jerk;
252+
else if (FLAVOR_IS(gcfRepRapFirmware))
236253
gcode << "M566 X" << jerk_x << " Y" << jerk_y;
237254
else
238255
gcode << "M205 X" << jerk_x << " Y" << jerk_y;
239256

240-
if (this->config.gcode_comments) gcode << " ; adjust jerk";
257+
if (this->config.gcode_comments)
258+
gcode << " ; adjust jerk (" << comment << ")";
259+
241260
gcode << "\n";
242261

243262
return gcode.str();

src/libslic3r/GCode/GCodeWriter.hpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "../Point.hpp"
1515
#include "../PrintConfig.hpp"
1616
#include "CoolingBuffer.hpp"
17+
#include "libslic3r/ExtrusionRole.hpp"
1718

1819
#include <string>
1920
#include <string_view>
@@ -29,7 +30,7 @@ class GCodeWriter {
2930
GCodeWriter() :
3031
multiple_extruders(false), m_extrusion_axis("E"), m_extruder(nullptr),
3132
m_single_extruder_multi_material(false),
32-
m_last_acceleration(0), m_max_acceleration(0), m_last_jerk(0),
33+
m_last_acceleration(0), m_max_acceleration(0), m_max_accel_to_decel(0), m_last_jerk(0),
3334
m_last_bed_temperature(0), m_last_bed_temperature_reached(true)
3435
{}
3536
Extruder* extruder() { return m_extruder; }
@@ -52,9 +53,9 @@ class GCodeWriter {
5253
std::string postamble() const;
5354
std::string set_temperature(unsigned int temperature, bool wait = false, int tool = -1) const;
5455
std::string set_bed_temperature(unsigned int temperature, bool wait = false);
55-
std::string set_print_acceleration(unsigned int acceleration) { return set_acceleration_internal(Acceleration::Print, acceleration); }
56-
std::string set_travel_acceleration(unsigned int acceleration) { return set_acceleration_internal(Acceleration::Travel, acceleration); }
57-
std::string set_jerk(unsigned int jerk);
56+
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); }
57+
std::string set_travel_acceleration(unsigned int acceleration, unsigned int accel_to_decel) { return set_acceleration_internal(Acceleration::Travel, acceleration, accel_to_decel, "Travel"); }
58+
std::string set_jerk(unsigned int jerk, const std::string_view comment);
5859
std::string reset_e(bool force = false);
5960
std::string update_progress(unsigned int num, unsigned int tot, bool allow_100 = false) const;
6061
// return false if this extruder was already selected
@@ -120,11 +121,13 @@ class GCodeWriter {
120121
bool m_single_extruder_multi_material;
121122
Extruder* m_extruder;
122123
unsigned int m_last_acceleration = (unsigned int)(-1);
124+
unsigned int m_last_accel_to_decel = (unsigned int)(-1);
123125
unsigned int m_last_travel_acceleration = (unsigned int)(-1); // only used for flavors supporting separate print/travel acc
124126
// Limit for setting the acceleration, to respect the machine limits set for the Marlin firmware.
125127
// If set to zero, the limit is not in action.
126128
unsigned int m_max_acceleration;
127129
unsigned int m_max_travel_acceleration;
130+
unsigned int m_max_accel_to_decel;
128131

129132
unsigned int m_last_jerk = (unsigned int)(-1);
130133
unsigned int m_max_jerk_x;
@@ -140,7 +143,7 @@ class GCodeWriter {
140143
};
141144

142145
std::string _retract(double length, double restart_extra, const std::string_view comment);
143-
std::string set_acceleration_internal(Acceleration type, unsigned int acceleration);
146+
std::string set_acceleration_internal(Acceleration type, unsigned int acceleration, unsigned int accel_to_decel, const std::string_view comment);
144147
};
145148

146149
class GCodeFormatter {

src/libslic3r/Preset.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -449,9 +449,10 @@ static std::vector<std::string> s_Preset_print_options {
449449
"perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "infill_speed", "solid_infill_speed",
450450
"enable_dynamic_overhang_speeds", "overhang_speed_0", "overhang_speed_1", "overhang_speed_2", "overhang_speed_3",
451451
"top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed",
452-
"bridge_speed", "gap_fill_speed", "gap_fill_enabled", "travel_speed", "travel_speed_z", "first_layer_speed", "first_layer_speed_over_raft", "perimeter_acceleration", "infill_acceleration",
453-
"external_perimeter_acceleration", "top_solid_infill_acceleration", "solid_infill_acceleration", "travel_acceleration",
454-
"bridge_acceleration", "first_layer_acceleration", "first_layer_acceleration_over_raft", "default_acceleration", "skirts", "skirt_distance", "skirt_height", "draft_shield",
452+
"bridge_speed", "gap_fill_speed", "gap_fill_enabled", "travel_speed", "travel_speed_z", "first_layer_speed", "first_layer_speed_over_raft", "perimeter_acceleration", "perimeter_accel_to_decel",
453+
"infill_acceleration", "infill_accel_to_decel", "external_perimeter_acceleration", "external_perimeter_accel_to_decel", "top_solid_infill_acceleration", "top_solid_infill_accel_to_decel",
454+
"solid_infill_acceleration", "solid_infill_accel_to_decel", "travel_acceleration", "travel_accel_to_decel", "bridge_acceleration", "bridge_accel_to_decel", "first_layer_acceleration",
455+
"first_layer_accel_to_decel", "first_layer_acceleration_over_raft", "first_layer_accel_to_decel_over_raft", "default_acceleration", "default_accel_to_decel", "skirts", "skirt_distance", "skirt_height", "draft_shield",
455456
"perimeter_jerk", "infill_jerk",
456457
"external_perimeter_jerk", "top_solid_infill_jerk", "solid_infill_jerk", "travel_jerk",
457458
"bridge_jerk", "first_layer_jerk", "first_layer_jerk_over_raft", "default_jerk",
@@ -508,7 +509,7 @@ static std::vector<std::string> s_Preset_filament_options {
508509
};
509510

510511
static std::vector<std::string> s_Preset_machine_limits_options {
511-
"machine_max_acceleration_extruding", "machine_max_acceleration_retracting", "machine_max_acceleration_travel",
512+
"machine_max_acceleration_extruding", "machine_max_acceleration_retracting", "machine_max_acceleration_travel", "machine_max_accel_to_decel",
512513
"machine_max_acceleration_x", "machine_max_acceleration_y", "machine_max_acceleration_z", "machine_max_acceleration_e",
513514
"machine_max_feedrate_x", "machine_max_feedrate_y", "machine_max_feedrate_z", "machine_max_feedrate_e",
514515
"machine_min_extruding_rate", "machine_min_travel_rate",

0 commit comments

Comments
 (0)