diff options
author | bubnikv <bubnikv@gmail.com> | 2018-08-04 18:38:25 +0300 |
---|---|---|
committer | bubnikv <bubnikv@gmail.com> | 2018-08-04 18:38:25 +0300 |
commit | 71b1e09af990b889488ab8797cbb9e5dcda5df5a (patch) | |
tree | 0d0c3a9caa6d75d2da74ad59227dd5205de1e359 /xs/src/libslic3r | |
parent | ac2b20b54b03cc67dd776681f7405ed4a93924ab (diff) |
T1 and M702 C are now evaluated by the time estimator to add the new
"filament_load_time" and "filament_unload_time" values to match
the MK3 MMU2 behavior.
Emitting of the remaining times into the output G-code was made optional
through a new "remaining_times" configuration value, so the firmware
flavors and versions, which do not know the M73 code, will not complain.
Configuration changes:
The wipe tower default position was shifted inwards after the wipe tower
coordinate reference point was changed from the center to the left front
corner.
Added the "filament_load_time" and "filament_unload_time" values
to the MK3 MMU filament profiles.
Enabled "remaining_times" for the MK2.5, MK3 and MK3MMU2 printers.
Diffstat (limited to 'xs/src/libslic3r')
-rw-r--r-- | xs/src/libslic3r/GCode.cpp | 8 | ||||
-rw-r--r-- | xs/src/libslic3r/GCodeReader.cpp | 22 | ||||
-rw-r--r-- | xs/src/libslic3r/GCodeReader.hpp | 1 | ||||
-rw-r--r-- | xs/src/libslic3r/GCodeTimeEstimator.cpp | 66 | ||||
-rw-r--r-- | xs/src/libslic3r/GCodeTimeEstimator.hpp | 15 | ||||
-rw-r--r-- | xs/src/libslic3r/PrintConfig.cpp | 10 | ||||
-rw-r--r-- | xs/src/libslic3r/PrintConfig.hpp | 2 |
7 files changed, 118 insertions, 6 deletions
diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index 1c1eeee6f..7edd55077 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -440,10 +440,9 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_ } fclose(file); - if (print->config.gcode_flavor.value == gcfMarlin) + if (print->config.remaining_times.value) { m_normal_time_estimator.post_process_remaining_times(path_tmp, 60.0f); - if (m_silent_time_estimator_enabled) m_silent_time_estimator.post_process_remaining_times(path_tmp, 60.0f); } @@ -525,8 +524,13 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, print.config.machine_max_jerk_y.values[1]); m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, print.config.machine_max_jerk_z.values[1]); m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, print.config.machine_max_jerk_e.values[1]); + m_silent_time_estimator.set_filament_load_times(print.config.filament_load_time.values); + m_silent_time_estimator.set_filament_unload_times(print.config.filament_unload_time.values); } } + // Filament load / unload times are not specific to a firmware flavor. Let anybody use it if they find it useful. + m_normal_time_estimator.set_filament_load_times(print.config.filament_load_time.values); + m_normal_time_estimator.set_filament_unload_times(print.config.filament_unload_time.values); // resets analyzer m_analyzer.reset(); diff --git a/xs/src/libslic3r/GCodeReader.cpp b/xs/src/libslic3r/GCodeReader.cpp index 965b7ef8e..79b6ed970 100644 --- a/xs/src/libslic3r/GCodeReader.cpp +++ b/xs/src/libslic3r/GCodeReader.cpp @@ -114,6 +114,28 @@ void GCodeReader::parse_file(const std::string &file, callback_t callback) this->parse_line(line, callback); } +bool GCodeReader::GCodeLine::has(char axis) const +{ + const char *c = m_raw.c_str(); + // Skip the whitespaces. + c = skip_whitespaces(c); + // Skip the command. + c = skip_word(c); + // Up to the end of line or comment. + while (! is_end_of_gcode_line(*c)) { + // Skip whitespaces. + c = skip_whitespaces(c); + if (is_end_of_gcode_line(*c)) + break; + // Check the name of the axis. + if (*c == axis) + return true; + // Skip the rest of the word. + c = skip_word(c); + } + return false; +} + bool GCodeReader::GCodeLine::has_value(char axis, float &value) const { const char *c = m_raw.c_str(); diff --git a/xs/src/libslic3r/GCodeReader.hpp b/xs/src/libslic3r/GCodeReader.hpp index 102cbd27a..84ed89a7c 100644 --- a/xs/src/libslic3r/GCodeReader.hpp +++ b/xs/src/libslic3r/GCodeReader.hpp @@ -27,6 +27,7 @@ public: bool has(Axis axis) const { return (m_mask & (1 << int(axis))) != 0; } float value(Axis axis) const { return m_axis[axis]; } + bool has(char axis) const; bool has_value(char axis, float &value) const; float new_Z(const GCodeReader &reader) const { return this->has(Z) ? this->z() : reader.z(); } float new_E(const GCodeReader &reader) const { return this->has(E) ? this->e() : reader.e(); } diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index 877695f39..b51692fc6 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -469,6 +469,40 @@ namespace Slic3r { return _state.minimum_travel_feedrate; } + void GCodeTimeEstimator::set_filament_load_times(const std::vector<double> &filament_load_times) + { + _state.filament_load_times.clear(); + for (double t : filament_load_times) + _state.filament_load_times.push_back(t); + } + + void GCodeTimeEstimator::set_filament_unload_times(const std::vector<double> &filament_unload_times) + { + _state.filament_unload_times.clear(); + for (double t : filament_unload_times) + _state.filament_unload_times.push_back(t); + } + + float GCodeTimeEstimator::get_filament_load_time(unsigned int id_extruder) + { + return + (_state.filament_load_times.empty() || id_extruder == _state.extruder_id_unloaded) ? + 0 : + (_state.filament_load_times.size() <= id_extruder) ? + _state.filament_load_times.front() : + _state.filament_load_times[id_extruder]; + } + + float GCodeTimeEstimator::get_filament_unload_time(unsigned int id_extruder) + { + return + (_state.filament_unload_times.empty() || id_extruder == _state.extruder_id_unloaded) ? + 0 : + (_state.filament_unload_times.size() <= id_extruder) ? + _state.filament_unload_times.front() : + _state.filament_unload_times[id_extruder]; + } + void GCodeTimeEstimator::set_extrude_factor_override_percentage(float percentage) { _state.extrude_factor_override_percentage = percentage; @@ -547,7 +581,9 @@ namespace Slic3r { void GCodeTimeEstimator::reset_extruder_id() { - _state.extruder_id = 0; + // Set the initial extruder ID to unknown. For the multi-material setup it means + // that all the filaments are parked in the MMU and no filament is loaded yet. + _state.extruder_id = _state.extruder_id_unloaded; } void GCodeTimeEstimator::add_additional_time(float timeSec) @@ -590,6 +626,9 @@ namespace Slic3r { set_axis_max_acceleration(axis, DEFAULT_AXIS_MAX_ACCELERATION[a]); set_axis_max_jerk(axis, DEFAULT_AXIS_MAX_JERK[a]); } + + _state.filament_load_times.clear(); + _state.filament_unload_times.clear(); } void GCodeTimeEstimator::reset() @@ -794,6 +833,11 @@ namespace Slic3r { _processM566(line); break; } + case 702: // MK3 MMU2: Process the final filament unload. + { + _processM702(line); + break; + } } break; @@ -1258,6 +1302,19 @@ namespace Slic3r { set_axis_max_jerk(E, line.e() * MMMIN_TO_MMSEC); } + void GCodeTimeEstimator::_processM702(const GCodeReader::GCodeLine& line) + { + PROFILE_FUNC(); + if (line.has('C')) { + // MK3 MMU2 specific M code: + // M702 C is expected to be sent by the custom end G-code when finalizing a print. + // The MK3 unit shall unload and park the active filament into the MMU2 unit. + add_additional_time(get_filament_unload_time(get_extruder_id())); + reset_extruder_id(); + _simulate_st_synchronize(); + } + } + void GCodeTimeEstimator::_processT(const GCodeReader::GCodeLine& line) { std::string cmd = line.cmd(); @@ -1266,9 +1323,12 @@ namespace Slic3r { unsigned int id = (unsigned int)::strtol(cmd.substr(1).c_str(), nullptr, 10); if (get_extruder_id() != id) { + // Specific to the MK3 MMU2: The initial extruder ID is set to -1 indicating + // that the filament is parked in the MMU2 unit and there is nothing to be unloaded yet. + add_additional_time(get_filament_unload_time(get_extruder_id())); set_extruder_id(id); - - // ADD PROCESSING HERE + add_additional_time(get_filament_load_time(get_extruder_id())); + _simulate_st_synchronize(); } } } diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index f6194a170..1fa74e304 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -79,7 +79,14 @@ namespace Slic3r { float minimum_feedrate; // mm/s float minimum_travel_feedrate; // mm/s float extrude_factor_override_percentage; + // Additional load / unload times for a filament exchange sequence. + std::vector<float> filament_load_times; + std::vector<float> filament_unload_times; unsigned int g1_line_id; + // extruder_id is currently used to correctly calculate filament load / unload times + // into the total print time. This is currently only really used by the MK3 MMU2: + // Extruder id (-1) means no filament is loaded yet, all the filaments are parked in the MK3 MMU2 unit. + static const unsigned int extruder_id_unloaded = (unsigned int)-1; unsigned int extruder_id; }; @@ -282,6 +289,11 @@ namespace Slic3r { void set_minimum_travel_feedrate(float feedrate_mm_sec); float get_minimum_travel_feedrate() const; + void set_filament_load_times(const std::vector<double> &filament_load_times); + void set_filament_unload_times(const std::vector<double> &filament_unload_times); + float get_filament_load_time(unsigned int id_extruder); + float get_filament_unload_time(unsigned int id_extruder); + void set_extrude_factor_override_percentage(float percentage); float get_extrude_factor_override_percentage() const; @@ -388,6 +400,9 @@ namespace Slic3r { // Set allowable instantaneous speed change void _processM566(const GCodeReader::GCodeLine& line); + // Unload the current filament into the MK3 MMU2 unit at the end of print. + void _processM702(const GCodeReader::GCodeLine& line); + // Processes T line (Select Tool) void _processT(const GCodeReader::GCodeLine& line); diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 1035951eb..fe1a75739 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -920,8 +920,16 @@ PrintConfigDef::PrintConfigDef() def->min = 0; def->default_value = new ConfigOptionFloat(0.3); + def = this->add("remaining_times", coBool); + def->label = L("Supports remaining times"); + def->tooltip = L("Emit M73 P[percent printed] R[remaining time in seconds] at 1 minute" + " intervals into the G-code to let the firmware show accurate remaining time." + " As of now only the Prusa i3 MK3 firmware recognizes M73." + " Also the i3 MK3 firmware supports M73 Qxx Sxx for the silent mode."); + def->default_value = new ConfigOptionBool(false); + def = this->add("silent_mode", coBool); - def->label = L("Support silent mode"); + def->label = L("Supports silent mode"); def->tooltip = L("Set silent mode for the G-code flavor"); def->default_value = new ConfigOptionBool(true); diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index 602f1f0aa..b18603d87 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -566,6 +566,7 @@ public: ConfigOptionFloat cooling_tube_retraction; ConfigOptionFloat cooling_tube_length; ConfigOptionFloat parking_pos_retraction; + ConfigOptionBool remaining_times; ConfigOptionBool silent_mode; ConfigOptionFloat extra_loading_move; @@ -631,6 +632,7 @@ protected: OPT_PTR(cooling_tube_retraction); OPT_PTR(cooling_tube_length); OPT_PTR(parking_pos_retraction); + OPT_PTR(remaining_times); OPT_PTR(silent_mode); OPT_PTR(extra_loading_move); } |